Changeset 38917 in webkit for trunk/JavaScriptCore
- Timestamp:
- Dec 2, 2008, 1:52:24 PM (17 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r38916 r38917 1 2008-12-02 Geoffrey Garen <[email protected]> 2 3 Reviewed by Geoffrey Garen. (Patch by Cameron Zwarich <[email protected]>.) 4 5 Fixed https://bugs.webkit.org/show_bug.cgi?id=22482 6 REGRESSION (r37991): Occasionally see "Scene rendered incorrectly" 7 message when running the V8 Raytrace benchmark 8 9 Rolled out r37991. It didn't properly save xmm0, which is caller-save, 10 before calling helper functions. 11 12 SunSpider and v8 benchmarks show little change -- possibly a .2% 13 SunSpider regression, possibly a .2% v8 benchmark speedup. 14 15 * assembler/X86Assembler.h: 16 (JSC::X86Assembler::): 17 * bytecode/CodeBlock.cpp: 18 (JSC::CodeBlock::dump): 19 * bytecode/Instruction.h: 20 (JSC::Instruction::): 21 * bytecompiler/BytecodeGenerator.cpp: 22 (JSC::BytecodeGenerator::emitUnaryOp): 23 * bytecompiler/BytecodeGenerator.h: 24 (JSC::BytecodeGenerator::emitToJSNumber): 25 (JSC::BytecodeGenerator::emitTypeOf): 26 (JSC::BytecodeGenerator::emitGetPropertyNames): 27 * interpreter/Interpreter.cpp: 28 (JSC::Interpreter::privateExecute): 29 * interpreter/Interpreter.h: 30 * jit/JIT.cpp: 31 (JSC::JIT::privateCompileMainPass): 32 (JSC::JIT::privateCompileSlowCases): 33 * jit/JIT.h: 34 * parser/Nodes.cpp: 35 (JSC::UnaryOpNode::emitBytecode): 36 (JSC::BinaryOpNode::emitBytecode): 37 (JSC::EqualNode::emitBytecode): 38 * parser/ResultType.h: 39 (JSC::ResultType::isReusable): 40 (JSC::ResultType::mightBeNumber): 41 * runtime/JSNumberCell.h: 42 1 43 2008-12-01 Gavin Barraclough <[email protected]> 2 44 -
trunk/JavaScriptCore/assembler/X86Assembler.h
r38857 r38917 124 124 OP2_CVTTSD2SI_GdWsd = 0x2C, 125 125 OP2_UCOMISD_VsdWsd = 0x2E, 126 OP2_XORPD_VsdWsd = 0x57,127 126 OP2_ADDSD_VsdWsd = 0x58, 128 127 OP2_MULSD_VsdWsd = 0x59, … … 160 159 161 160 GROUP3_OP_TEST = 0, 162 GROUP3_OP_NEG = 3,163 161 GROUP3_OP_IDIV = 7, 164 162 … … 591 589 } 592 590 593 void negl_r(RegisterID dst)594 {595 m_buffer->putByte(OP_GROUP3_Ev);596 modRm_opr(GROUP3_OP_NEG, dst);597 }598 599 591 void cdq() 600 592 { … … 770 762 modRm_rm((RegisterID)dst, base, offset); 771 763 } 772 773 #if !PLATFORM(X86_64)774 void xorpd_mr(void* addr, XMMRegisterID dst)775 {776 m_buffer->putByte(PRE_SSE_66);777 m_buffer->putByte(OP_2BYTE_ESCAPE);778 m_buffer->putByte(OP2_XORPD_VsdWsd);779 modRm_rm((RegisterID)dst, addr);780 }781 #endif782 764 783 765 void movsd_rm(XMMRegisterID src, int offset, RegisterID base) -
trunk/JavaScriptCore/bytecode/CodeBlock.cpp
r38688 r38917 469 469 case op_negate: { 470 470 printUnaryOp(location, it, "negate"); 471 ++it;472 471 break; 473 472 } -
trunk/JavaScriptCore/bytecode/Instruction.h
r38763 r38917 31 31 32 32 #include "Opcode.h" 33 #include "ResultType.h"34 33 #include <wtf/VectorTraits.h> 35 34 … … 139 138 StructureChain* structureChain; 140 139 JSCell* jsCell; 141 ResultType::Type resultType;142 140 PolymorphicAccessStructureList* polymorphicStructures; 143 141 } u; -
trunk/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r38887 r38917 750 750 } 751 751 752 RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src , ResultType type)752 RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src) 753 753 { 754 754 emitOpcode(opcodeID); 755 755 instructions().append(dst->index()); 756 756 instructions().append(src->index()); 757 if (opcodeID == op_negate)758 instructions().append(type.toInt());759 757 return dst; 760 758 } -
trunk/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r38511 r38917 232 232 RegisterID* emitUnexpectedLoad(RegisterID* dst, double); 233 233 234 RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src , ResultType);234 RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src); 235 235 RegisterID* emitBinaryOp(OpcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes); 236 236 RegisterID* emitEqualityOp(OpcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2); … … 246 246 RegisterID* emitMove(RegisterID* dst, RegisterID* src); 247 247 248 RegisterID* emitToJSNumber(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_to_jsnumber, dst, src , ResultType::unknown()); }248 RegisterID* emitToJSNumber(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_to_jsnumber, dst, src); } 249 249 RegisterID* emitPreInc(RegisterID* srcDst); 250 250 RegisterID* emitPreDec(RegisterID* srcDst); … … 253 253 254 254 RegisterID* emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* base, RegisterID* basePrototype); 255 RegisterID* emitTypeOf(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_typeof, dst, src , ResultType::unknown()); }255 RegisterID* emitTypeOf(RegisterID* dst, RegisterID* src) { return emitUnaryOp(op_typeof, dst, src); } 256 256 RegisterID* emitIn(RegisterID* dst, RegisterID* property, RegisterID* base) { return emitBinaryOp(op_in, dst, property, base, OperandTypes()); } 257 257 … … 291 291 void emitSubroutineReturn(RegisterID* retAddrSrc); 292 292 293 RegisterID* emitGetPropertyNames(RegisterID* dst, RegisterID* base) { return emitUnaryOp(op_get_pnames, dst, base , ResultType::unknown()); }293 RegisterID* emitGetPropertyNames(RegisterID* dst, RegisterID* base) { return emitUnaryOp(op_get_pnames, dst, base); } 294 294 RegisterID* emitNextPropertyName(RegisterID* dst, RegisterID* iter, Label* target); 295 295 -
trunk/JavaScriptCore/interpreter/Interpreter.cpp
r38839 r38917 1874 1874 } 1875 1875 1876 ++vPC;1877 1876 NEXT_INSTRUCTION(); 1878 1877 } -
trunk/JavaScriptCore/interpreter/Interpreter.h
r38839 r38917 273 273 static void SFX_CALL cti_op_debug(CTI_ARGS); 274 274 275 static JSValue* SFX_CALL cti_allocate_number(CTI_ARGS);276 277 275 static JSValue* SFX_CALL cti_vm_throw(CTI_ARGS); 278 276 static void* SFX_CALL cti_vm_dontLazyLinkCall(CTI_ARGS); -
trunk/JavaScriptCore/jit/JIT.cpp
r38916 r38917 362 362 #endif 363 363 364 extern "C" {365 static JSValue* FASTCALL allocateNumber(JSGlobalData* globalData) {366 JSValue* result = new (globalData) JSNumberCell(globalData);367 ASSERT(result);368 return result;369 }370 }371 372 ALWAYS_INLINE void JIT::emitAllocateNumber(JSGlobalData* globalData, unsigned bytecodeIndex)373 {374 __ movl_i32r(reinterpret_cast<intptr_t>(globalData), X86::ecx);375 emitNakedFastCall(bytecodeIndex, (void*)allocateNumber);376 }377 378 364 ALWAYS_INLINE JmpSrc JIT::emitNakedCall(unsigned bytecodeIndex, X86::RegisterID r) 379 365 { … … 385 371 386 372 ALWAYS_INLINE JmpSrc JIT::emitNakedCall(unsigned bytecodeIndex, void* function) 387 {388 JmpSrc call = __ call();389 m_calls.append(CallRecord(call, reinterpret_cast<CTIHelper_v>(function), bytecodeIndex));390 return call;391 }392 393 ALWAYS_INLINE JmpSrc JIT::emitNakedFastCall(unsigned bytecodeIndex, void* function)394 373 { 395 374 JmpSrc call = __ call(); … … 602 581 __ addl_rr(reg, reg); 603 582 emitFastArithReTagImmediate(reg); 604 }605 606 ALWAYS_INLINE JmpSrc JIT::emitArithIntToImmWithJump(RegisterID reg)607 {608 __ addl_rr(reg, reg);609 JmpSrc jmp = __ jo();610 emitFastArithReTagImmediate(reg);611 return jmp;612 583 } 613 584 … … 1597 1568 } 1598 1569 case op_negate: { 1599 int srcVReg = instruction[i + 2].u.operand; 1600 emitGetVirtualRegister(srcVReg, X86::eax, i); 1601 1602 __ testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax); 1603 JmpSrc notImmediate = __ je(); 1604 1605 __ cmpl_i32r(JSImmediate::TagBitTypeInteger, X86::eax); 1606 JmpSrc zeroImmediate = __ je(); 1607 emitFastArithImmToInt(X86::eax); 1608 __ negl_r(X86::eax); // This can't overflow as we only have a 31bit int at this point 1609 JmpSrc overflow = emitArithIntToImmWithJump(X86::eax); 1610 emitPutVirtualRegister(instruction[i + 1].u.operand); 1611 JmpSrc immediateNegateSuccess = __ jmp(); 1612 1613 if (!isSSE2Present()) { 1614 __ link(zeroImmediate, __ label()); 1615 __ link(overflow, __ label()); 1616 __ link(notImmediate, __ label()); 1617 emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 0, X86::ecx); 1618 emitCTICall(i, Interpreter::cti_op_negate); 1619 emitPutVirtualRegister(instruction[i + 1].u.operand); 1620 } else { 1621 // Slow case immediates 1622 m_slowCases.append(SlowCaseEntry(zeroImmediate, i)); 1623 m_slowCases.append(SlowCaseEntry(overflow, i)); 1624 __ link(notImmediate, __ label()); 1625 ResultType resultType(instruction[i + 3].u.resultType); 1626 if (!resultType.definitelyIsNumber()) { 1627 emitJumpSlowCaseIfNotJSCell(X86::eax, i, srcVReg); 1628 Structure* numberStructure = m_globalData->numberStructure.get(); 1629 __ cmpl_i32m(reinterpret_cast<unsigned>(numberStructure), FIELD_OFFSET(JSCell, m_structure), X86::eax); 1630 m_slowCases.append(SlowCaseEntry(__ jne(), i)); 1631 } 1632 __ movsd_mr(FIELD_OFFSET(JSNumberCell, m_value), X86::eax, X86::xmm0); 1633 // We need 3 copies of the sign bit mask so we can assure alignment and pad for the 128bit load 1634 static double doubleSignBit[] = { -0.0, -0.0, -0.0 }; 1635 __ xorpd_mr((void*)((((uintptr_t)doubleSignBit)+15)&~15), X86::xmm0); 1636 JmpSrc wasCell; 1637 if (!resultType.isReusableNumber()) 1638 emitAllocateNumber(m_globalData, i); 1639 1640 putDoubleResultToJSNumberCellOrJSImmediate(X86::xmm0, X86::eax, instruction[i + 1].u.operand, &wasCell, 1641 X86::xmm1, X86::ecx, X86::edx); 1642 __ link(wasCell, __ label()); 1643 } 1644 __ link(immediateNegateSuccess, __ label()); 1645 i += 4; 1570 emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 0, X86::ecx); 1571 emitCTICall(i, Interpreter::cti_op_negate); 1572 emitPutVirtualRegister(instruction[i + 1].u.operand); 1573 i += 3; 1646 1574 break; 1647 1575 } … … 2486 2414 break; 2487 2415 } 2488 case op_negate: {2489 __ link(iter->from, __ label());2490 __ link((++iter)->from, __ label());2491 ResultType resultType(instruction[i + 3].u.resultType);2492 if (!resultType.definitelyIsNumber()) {2493 if (linkSlowCaseIfNotJSCell(++iter, instruction[i + 2].u.operand))2494 ++iter;2495 __ link(iter->from, __ label());2496 }2497 2498 emitPutCTIArgFromVirtualRegister(instruction[i + 2].u.operand, 0, X86::ecx);2499 emitCTICall(i, Interpreter::cti_op_negate);2500 emitPutVirtualRegister(instruction[i + 1].u.operand);2501 i += 4;2502 break;2503 }2504 2416 case op_rshift: { 2505 2417 __ link(iter->from, __ label()); -
trunk/JavaScriptCore/jit/JIT.h
r38916 r38917 87 87 #define CTI_RETURN_ADDRESS_SLOT (ARGS[-1]) 88 88 89 #if COMPILER(MSVC)90 #define FASTCALL __fastcall91 #elif COMPILER(GCC)92 #define FASTCALL __attribute__ ((fastcall))93 #else94 #error Need to support fastcall calling convention in this compiler95 #endif96 97 89 namespace JSC { 98 90 … … 449 441 void emitFastArithIntToImmOrSlowCase(RegisterID, unsigned bytecodeIndex); 450 442 void emitFastArithIntToImmNoCheck(RegisterID); 451 JmpSrc emitArithIntToImmWithJump(RegisterID reg);452 443 453 444 void emitTagAsBoolImmediate(RegisterID reg); 454 455 void emitAllocateNumber(JSGlobalData*, unsigned);456 445 457 446 JmpSrc emitNakedCall(unsigned bytecodeIndex, RegisterID); 458 447 JmpSrc emitNakedCall(unsigned bytecodeIndex, void* function); 459 JmpSrc emitNakedFastCall(unsigned bytecodeIndex, void*);460 448 JmpSrc emitCTICall(unsigned bytecodeIndex, CTIHelper_j); 461 449 JmpSrc emitCTICall(unsigned bytecodeIndex, CTIHelper_o); -
trunk/JavaScriptCore/parser/Nodes.cpp
r38747 r38917 1094 1094 { 1095 1095 RegisterID* src = generator.emitNode(m_expr.get()); 1096 return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src , m_expr->resultDescriptor());1096 return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src); 1097 1097 } 1098 1098 … … 1116 1116 if (m_expr1->isNull() || m_expr2->isNull()) { 1117 1117 RefPtr<RegisterID> src = generator.emitNode(dst, m_expr1->isNull() ? m_expr2.get() : m_expr1.get()); 1118 return generator.emitUnaryOp(op_neq_null, generator.finalDestination(dst, src.get()), src.get() , ResultType::unknown());1118 return generator.emitUnaryOp(op_neq_null, generator.finalDestination(dst, src.get()), src.get()); 1119 1119 } 1120 1120 } … … 1129 1129 if (m_expr1->isNull() || m_expr2->isNull()) { 1130 1130 RefPtr<RegisterID> src = generator.emitNode(dst, m_expr1->isNull() ? m_expr2.get() : m_expr1.get()); 1131 return generator.emitUnaryOp(op_eq_null, generator.finalDestination(dst, src.get()), src.get() , ResultType::unknown());1131 return generator.emitUnaryOp(op_eq_null, generator.finalDestination(dst, src.get()), src.get()); 1132 1132 } 1133 1133 -
trunk/JavaScriptCore/parser/ResultType.h
r38205 r38917 53 53 return (m_type & TypeReusable); 54 54 } 55 56 bool isReusableNumber()57 {58 return isReusable() && definitelyIsNumber();59 }60 55 61 56 bool definitelyIsNumber() … … 72 67 { 73 68 return !isNotNumber(); 74 }75 76 int toInt()77 {78 return static_cast<int>(m_type);79 69 } 80 70 -
trunk/JavaScriptCore/runtime/JSNumberCell.h
r38528 r38917 85 85 static PassRefPtr<Structure> createStructure(JSValue* proto) { return Structure::create(proto, TypeInfo(NumberType, NeedsThisConversion)); } 86 86 87 JSNumberCell(JSGlobalData* globalData)88 : JSCell(globalData->numberStructure.get())89 {90 }91 92 87 private: 93 88 JSNumberCell(JSGlobalData* globalData, double value)
Note:
See TracChangeset
for help on using the changeset viewer.