diff options
Diffstat (limited to 'Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp')
-rw-r--r-- | Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp | 120 |
1 files changed, 41 insertions, 79 deletions
diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp index 710a155..3562200 100644 --- a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp +++ b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp @@ -225,9 +225,9 @@ void JIT::emit_op_method_check(Instruction* currentInstruction) move(Imm32(JSValue::CellTag), regT1); Jump match = jump(); - ASSERT(differenceBetween(info.structureToCompare, protoObj) == patchOffsetMethodCheckProtoObj); - ASSERT(differenceBetween(info.structureToCompare, protoStructureToCompare) == patchOffsetMethodCheckProtoStruct); - ASSERT(differenceBetween(info.structureToCompare, putFunction) == patchOffsetMethodCheckPutFunction); + ASSERT_JIT_OFFSET(differenceBetween(info.structureToCompare, protoObj), patchOffsetMethodCheckProtoObj); + ASSERT_JIT_OFFSET(differenceBetween(info.structureToCompare, protoStructureToCompare), patchOffsetMethodCheckProtoStruct); + ASSERT_JIT_OFFSET(differenceBetween(info.structureToCompare, putFunction), patchOffsetMethodCheckPutFunction); // Link the failure cases here. structureCheck.link(this); @@ -431,21 +431,17 @@ void JIT::compileGetByIdHotPath() DataLabelPtr structureToCompare; Jump structureCheck = branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure))); addSlowCase(structureCheck); - ASSERT(differenceBetween(hotPathBegin, structureToCompare) == patchOffsetGetByIdStructure); - ASSERT(differenceBetween(hotPathBegin, structureCheck) == patchOffsetGetByIdBranchToSlowCase); - - Label externalLoad = loadPtrWithPatchToLEA(Address(regT0, OBJECT_OFFSETOF(JSObject, m_externalStorage)), regT2); - Label externalLoadComplete(this); - ASSERT(differenceBetween(hotPathBegin, externalLoad) == patchOffsetGetByIdExternalLoad); - ASSERT(differenceBetween(externalLoad, externalLoadComplete) == patchLengthGetByIdExternalLoad); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureToCompare), patchOffsetGetByIdStructure); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureCheck), patchOffsetGetByIdBranchToSlowCase); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), regT2); DataLabel32 displacementLabel1 = loadPtrWithAddressOffsetPatch(Address(regT2, patchGetByIdDefaultOffset), regT0); // payload - ASSERT(differenceBetween(hotPathBegin, displacementLabel1) == patchOffsetGetByIdPropertyMapOffset1); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, displacementLabel1), patchOffsetGetByIdPropertyMapOffset1); DataLabel32 displacementLabel2 = loadPtrWithAddressOffsetPatch(Address(regT2, patchGetByIdDefaultOffset), regT1); // tag - ASSERT(differenceBetween(hotPathBegin, displacementLabel2) == patchOffsetGetByIdPropertyMapOffset2); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, displacementLabel2), patchOffsetGetByIdPropertyMapOffset2); Label putResult(this); - ASSERT(differenceBetween(hotPathBegin, putResult) == patchOffsetGetByIdPutResult); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, putResult), patchOffsetGetByIdPutResult); END_UNINTERRUPTED_SEQUENCE(sequenceGetByIdHotPath); } @@ -481,7 +477,7 @@ void JIT::compileGetByIdSlowCase(int dst, int base, Identifier* ident, Vector<Sl END_UNINTERRUPTED_SEQUENCE(sequenceGetByIdSlowCase); - ASSERT(differenceBetween(coldPathBegin, call) == patchOffsetGetByIdSlowCaseCall); + ASSERT_JIT_OFFSET(differenceBetween(coldPathBegin, call), patchOffsetGetByIdSlowCaseCall); // Track the location of the call; this will be used to recover patch information. m_propertyAccessCompilationInfo[m_propertyAccessInstructionIndex].callReturnLocation = call; @@ -510,21 +506,16 @@ void JIT::emit_op_put_by_id(Instruction* currentInstruction) // It is important that the following instruction plants a 32bit immediate, in order that it can be patched over. DataLabelPtr structureToCompare; addSlowCase(branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)))); - ASSERT(differenceBetween(hotPathBegin, structureToCompare) == patchOffsetPutByIdStructure); - - // Plant a load from a bogus ofset in the object's property map; we will patch this later, if it is to be used. - Label externalLoad = loadPtrWithPatchToLEA(Address(regT0, OBJECT_OFFSETOF(JSObject, m_externalStorage)), regT0); - Label externalLoadComplete(this); - ASSERT(differenceBetween(hotPathBegin, externalLoad) == patchOffsetPutByIdExternalLoad); - ASSERT(differenceBetween(externalLoad, externalLoadComplete) == patchLengthPutByIdExternalLoad); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureToCompare), patchOffsetPutByIdStructure); + loadPtr(Address(regT0, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), regT0); DataLabel32 displacementLabel1 = storePtrWithAddressOffsetPatch(regT2, Address(regT0, patchGetByIdDefaultOffset)); // payload DataLabel32 displacementLabel2 = storePtrWithAddressOffsetPatch(regT3, Address(regT0, patchGetByIdDefaultOffset)); // tag END_UNINTERRUPTED_SEQUENCE(sequencePutById); - ASSERT(differenceBetween(hotPathBegin, displacementLabel1) == patchOffsetPutByIdPropertyMapOffset1); - ASSERT(differenceBetween(hotPathBegin, displacementLabel2) == patchOffsetPutByIdPropertyMapOffset2); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, displacementLabel1), patchOffsetPutByIdPropertyMapOffset1); + ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, displacementLabel2), patchOffsetPutByIdPropertyMapOffset2); } void JIT::emitSlow_op_put_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -552,9 +543,9 @@ void JIT::compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterI { int offset = cachedOffset; if (structure->isUsingInlineStorage()) - offset += OBJECT_OFFSETOF(JSObject, m_inlineStorage) / sizeof(Register); + offset += JSObject::offsetOfInlineStorage() / sizeof(Register); else - loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base); + loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), base); emitStore(offset, valueTag, valuePayload, base); } @@ -562,27 +553,20 @@ void JIT::compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterI void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, Structure* structure, size_t cachedOffset) { int offset = cachedOffset; - if (structure->isUsingInlineStorage()) - offset += OBJECT_OFFSETOF(JSObject, m_inlineStorage) / sizeof(Register); - else - loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base); - emitLoad(offset, resultTag, resultPayload, base); + if (structure->isUsingInlineStorage()) { + offset += JSObject::offsetOfInlineStorage() / sizeof(Register); + emitLoad(offset, resultTag, resultPayload, base); + } else { + RegisterID temp = resultPayload; + loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), temp); + emitLoad(offset, resultTag, resultPayload, temp); + } } -void JIT::compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset) +void JIT::compileGetDirectOffset(JSObject* base, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset) { - if (base->isUsingInlineStorage()) { - load32(reinterpret_cast<char*>(&base->m_inlineStorage[cachedOffset]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload), resultPayload); - load32(reinterpret_cast<char*>(&base->m_inlineStorage[cachedOffset]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag), resultTag); - return; - } - - size_t offset = cachedOffset * sizeof(JSValue); - - PropertyStorage* protoPropertyStorage = &base->m_externalStorage; - loadPtr(static_cast<void*>(protoPropertyStorage), temp); - load32(Address(temp, offset + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload); - load32(Address(temp, offset + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag); + load32(reinterpret_cast<char*>(&base->m_propertyStorage[cachedOffset]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload), resultPayload); + load32(reinterpret_cast<char*>(&base->m_propertyStorage[cachedOffset]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag), resultTag); } void JIT::testPrototype(JSValue prototype, JumpList& failureCases) @@ -683,12 +667,7 @@ void JIT::patchGetByIdSelf(CodeBlock* codeBlock, StructureStubInfo* stubInfo, St repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_self_fail)); int offset = sizeof(JSValue) * cachedOffset; - - // If we're patching to use inline storage, convert the initial load to a lea; this avoids the extra load - // and makes the subsequent load's offset automatically correct - if (structure->isUsingInlineStorage()) - repatchBuffer.repatchLoadPtrToLEA(stubInfo->hotPathBegin.instructionAtOffset(patchOffsetGetByIdExternalLoad)); - + // Patch the offset into the propoerty map to load from, then patch the Structure to look for. repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(patchOffsetGetByIdStructure), structure); repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetGetByIdPropertyMapOffset1), offset + OBJECT_OFFSETOF(JSValue, u.asBits.payload)); // payload @@ -724,12 +703,7 @@ void JIT::patchPutByIdReplace(CodeBlock* codeBlock, StructureStubInfo* stubInfo, repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic)); int offset = sizeof(JSValue) * cachedOffset; - - // If we're patching to use inline storage, convert the initial load to a lea; this avoids the extra load - // and makes the subsequent load's offset automatically correct - if (structure->isUsingInlineStorage()) - repatchBuffer.repatchLoadPtrToLEA(stubInfo->hotPathBegin.instructionAtOffset(patchOffsetPutByIdExternalLoad)); - + // Patch the offset into the propoerty map to load from, then patch the Structure to look for. repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(patchOffsetPutByIdStructure), structure); repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetPutByIdPropertyMapOffset1), offset + OBJECT_OFFSETOF(JSValue, u.asBits.payload)); // payload @@ -799,7 +773,7 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str // Checks out okay! if (slot.cachedPropertyType() == PropertySlot::Getter) { needsStubLink = true; - compileGetDirectOffset(protoObject, regT2, regT2, regT1, cachedOffset); + compileGetDirectOffset(protoObject, regT2, regT1, cachedOffset); JITStubCall stubCall(this, cti_op_get_by_id_getter_stub); stubCall.addArgument(regT1); stubCall.addArgument(regT0); @@ -814,7 +788,7 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress())); stubCall.call(); } else - compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset); + compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset); Jump success = jump(); @@ -856,11 +830,7 @@ void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, Polymorphic bool needsStubLink = false; if (slot.cachedPropertyType() == PropertySlot::Getter) { needsStubLink = true; - if (!structure->isUsingInlineStorage()) { - move(regT0, regT1); - compileGetDirectOffset(regT1, regT2, regT1, structure, cachedOffset); - } else - compileGetDirectOffset(regT0, regT2, regT1, structure, cachedOffset); + compileGetDirectOffset(regT0, regT2, regT1, structure, cachedOffset); JITStubCall stubCall(this, cti_op_get_by_id_getter_stub); stubCall.addArgument(regT1); stubCall.addArgument(regT0); @@ -930,7 +900,7 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi bool needsStubLink = false; if (slot.cachedPropertyType() == PropertySlot::Getter) { needsStubLink = true; - compileGetDirectOffset(protoObject, regT2, regT2, regT1, cachedOffset); + compileGetDirectOffset(protoObject, regT2, regT1, cachedOffset); JITStubCall stubCall(this, cti_op_get_by_id_getter_stub); stubCall.addArgument(regT1); stubCall.addArgument(regT0); @@ -945,7 +915,7 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress())); stubCall.call(); } else - compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset); + compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset); Jump success = jump(); @@ -999,7 +969,7 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi bool needsStubLink = false; if (slot.cachedPropertyType() == PropertySlot::Getter) { needsStubLink = true; - compileGetDirectOffset(protoObject, regT2, regT2, regT1, cachedOffset); + compileGetDirectOffset(protoObject, regT2, regT1, cachedOffset); JITStubCall stubCall(this, cti_op_get_by_id_getter_stub); stubCall.addArgument(regT1); stubCall.addArgument(regT0); @@ -1014,7 +984,7 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress())); stubCall.call(); } else - compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset); + compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset); Jump success = jump(); @@ -1069,7 +1039,7 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str bool needsStubLink = false; if (slot.cachedPropertyType() == PropertySlot::Getter) { needsStubLink = true; - compileGetDirectOffset(protoObject, regT2, regT2, regT1, cachedOffset); + compileGetDirectOffset(protoObject, regT2, regT1, cachedOffset); JITStubCall stubCall(this, cti_op_get_by_id_getter_stub); stubCall.addArgument(regT1); stubCall.addArgument(regT0); @@ -1084,7 +1054,7 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress())); stubCall.call(); } else - compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset); + compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset); Jump success = jump(); LinkBuffer patchBuffer(this, m_codeBlock->executablePool(), 0); @@ -1117,21 +1087,13 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str #endif // !ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) -void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID structure, RegisterID offset) +void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID offset) { - ASSERT(sizeof(((Structure*)0)->m_propertyStorageCapacity) == sizeof(int32_t)); - ASSERT(sizeof(JSObject::inlineStorageCapacity) == sizeof(int32_t)); ASSERT(sizeof(JSValue) == 8); - Jump notUsingInlineStorage = branch32(NotEqual, Address(structure, OBJECT_OFFSETOF(Structure, m_propertyStorageCapacity)), Imm32(JSObject::inlineStorageCapacity)); - loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSObject, m_inlineStorage) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload); - loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSObject, m_inlineStorage) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag); - Jump finishedLoad = jump(); - notUsingInlineStorage.link(this); - loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base); + loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), base); loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload); loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag); - finishedLoad.link(this); } void JIT::emit_op_get_by_pname(Instruction* currentInstruction) @@ -1156,7 +1118,7 @@ void JIT::emit_op_get_by_pname(Instruction* currentInstruction) load32(addressFor(i), regT3); sub32(Imm32(1), regT3); addSlowCase(branch32(AboveOrEqual, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_numCacheableSlots)))); - compileGetDirectOffset(regT2, regT1, regT0, regT0, regT3); + compileGetDirectOffset(regT2, regT1, regT0, regT3); emitStore(dst, regT1, regT0); map(m_bytecodeOffset + OPCODE_LENGTH(op_get_by_pname), dst, regT1, regT0); |