Changeset 78732 in webkit for trunk/Source/JavaScriptCore/jit


Ignore:
Timestamp:
Feb 16, 2011, 1:35:19 PM (14 years ago)
Author:
[email protected]
Message:

Bug 54524 - Allow JSObject to fully utilize cell's capacity for inline storage.

Reviewed by Geoff Garen.

Currently JSObject is both directly instantiated for regular JS objects, and
derived to implement subtypes. A consequence of this is that we need to ensure
that sufficient space from the cell is left unused and available for any data
members that will be introduced by subclasses of JSObject. By restructuring
the internal storage array out of JSObject we can increase the size in the
internal storage for regular objects.

Add classes JSFinalObject and JSNonFinalObject. JSNonFinalObject retains as
much additional capacity as is currently available to allow for data members
in subclasses. JSFinalObject utilizes all available space for internal storage,
and only allows construction through JSFinalObject::create().

Source/JavaScriptCore:

The additional storage made available in the JSObject means that we need no
longer rely on a union of the internal storage with a pointer to storage that
is only valid for external storage. This means we can go back to always having
a valid pointer to property storage, regardless of whether this is internal or
external. This simplifies some cases of access to the array from C code, and
significantly simplifies JIT access, since repatching no longer needs to be
able to change between a load of the storage pointer / a LEA of the internal
storage.

  • API/JSObjectRef.cpp:

(JSObjectMake):

  • assembler/ARMAssembler.h:
  • assembler/ARMv7Assembler.h:
  • assembler/AbstractMacroAssembler.h:

(JSC::AbstractMacroAssembler::repatchPointer):

  • assembler/MIPSAssembler.h:
  • assembler/MacroAssemblerARM.h:
  • assembler/MacroAssemblerARMv7.h:
  • assembler/MacroAssemblerMIPS.h:
  • assembler/MacroAssemblerX86.h:
  • assembler/MacroAssemblerX86_64.h:
  • assembler/RepatchBuffer.h:
  • assembler/X86Assembler.h:
  • debugger/DebuggerActivation.cpp:

(JSC::DebuggerActivation::DebuggerActivation):

  • debugger/DebuggerActivation.h:
  • interpreter/Interpreter.cpp:

(JSC::Interpreter::privateExecute):

  • jit/JIT.h:
  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_resolve_global):

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::emit_op_resolve_global):

  • jit/JITPropertyAccess.cpp:

(JSC::JIT::compileGetDirectOffset):
(JSC::JIT::emit_op_get_by_pname):
(JSC::JIT::compileGetByIdHotPath):
(JSC::JIT::emit_op_put_by_id):
(JSC::JIT::compilePutDirectOffset):
(JSC::JIT::patchGetByIdSelf):
(JSC::JIT::patchPutByIdReplace):
(JSC::JIT::privateCompileGetByIdProto):
(JSC::JIT::privateCompileGetByIdSelfList):
(JSC::JIT::privateCompileGetByIdProtoList):
(JSC::JIT::privateCompileGetByIdChainList):
(JSC::JIT::privateCompileGetByIdChain):

  • jit/JITPropertyAccess32_64.cpp:

(JSC::JIT::compileGetByIdHotPath):
(JSC::JIT::emit_op_put_by_id):
(JSC::JIT::compilePutDirectOffset):
(JSC::JIT::compileGetDirectOffset):
(JSC::JIT::patchGetByIdSelf):
(JSC::JIT::patchPutByIdReplace):
(JSC::JIT::privateCompileGetByIdProto):
(JSC::JIT::privateCompileGetByIdSelfList):
(JSC::JIT::privateCompileGetByIdProtoList):
(JSC::JIT::privateCompileGetByIdChainList):
(JSC::JIT::privateCompileGetByIdChain):
(JSC::JIT::emit_op_get_by_pname):

  • jit/JITStubs.cpp:

(JSC::DEFINE_STUB_FUNCTION):

  • runtime/Arguments.h:

(JSC::Arguments::Arguments):

  • runtime/ErrorInstance.cpp:

(JSC::ErrorInstance::ErrorInstance):

  • runtime/ErrorInstance.h:
  • runtime/ExceptionHelpers.cpp:

(JSC::InterruptedExecutionError::InterruptedExecutionError):
(JSC::TerminatedExecutionError::TerminatedExecutionError):

  • runtime/JSArray.cpp:

(JSC::JSArray::JSArray):

  • runtime/JSArray.h:
  • runtime/JSByteArray.cpp:

(JSC::JSByteArray::JSByteArray):

  • runtime/JSByteArray.h:

(JSC::JSByteArray::JSByteArray):

  • runtime/JSFunction.cpp:

(JSC::JSFunction::getOwnPropertySlot):

  • runtime/JSGlobalData.cpp:

(JSC::JSGlobalData::JSGlobalData):

  • runtime/JSGlobalObject.h:

(JSC::constructEmptyObject):

  • runtime/JSNotAnObject.h:

(JSC::JSNotAnObject::JSNotAnObject):

  • runtime/JSObject.cpp:

(JSC::JSObject::createInheritorID):
(JSC::JSObject::allocatePropertyStorage):

  • runtime/JSObject.h:

(JSC::JSObject::propertyStorage):
(JSC::JSNonFinalObject::JSNonFinalObject):
(JSC::JSNonFinalObject::createStructure):
(JSC::JSFinalObject::create):
(JSC::JSFinalObject::createStructure):
(JSC::JSFinalObject::JSFinalObject):
(JSC::JSObject::offsetOfInlineStorage):
(JSC::constructEmptyObject):
(JSC::createEmptyObjectStructure):
(JSC::JSObject::JSObject):
(JSC::JSObject::~JSObject):
(JSC::Structure::isUsingInlineStorage):

  • runtime/JSObjectWithGlobalObject.cpp:

(JSC::JSObjectWithGlobalObject::JSObjectWithGlobalObject):

  • runtime/JSObjectWithGlobalObject.h:

(JSC::JSObjectWithGlobalObject::JSObjectWithGlobalObject):

  • runtime/JSTypeInfo.h:

(JSC::TypeInfo::TypeInfo):
(JSC::TypeInfo::isVanilla):

  • runtime/JSVariableObject.h:

(JSC::JSVariableObject::JSVariableObject):

  • runtime/JSWrapperObject.h:

(JSC::JSWrapperObject::JSWrapperObject):

  • runtime/ObjectConstructor.cpp:

(JSC::constructObject):

  • runtime/ObjectPrototype.cpp:

(JSC::ObjectPrototype::ObjectPrototype):

  • runtime/ObjectPrototype.h:
  • runtime/StrictEvalActivation.cpp:

(JSC::StrictEvalActivation::StrictEvalActivation):

  • runtime/StrictEvalActivation.h:
  • runtime/Structure.cpp:

(JSC::Structure::Structure):
(JSC::Structure::growPropertyStorageCapacity):

Source/JavaScriptGlue:

  • UserObjectImp.cpp:
  • UserObjectImp.h:

Update JSObject -> JSNonFinalObject.

Source/WebCore:

  • bindings/js/JSDOMWindowShell.h:

Update JSObject -> JSNonFinalObject.

Location:
trunk/Source/JavaScriptCore/jit
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r78174 r78732  
    333333#endif
    334334        void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, Structure* structure, size_t cachedOffset);
    335         void compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset);
    336         void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID structure, RegisterID offset);
     335        void compileGetDirectOffset(JSObject* base, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset);
     336        void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID offset);
    337337        void compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterID valuePayload, Structure* structure, size_t cachedOffset);
    338338
     
    345345        // These architecture specific value are used to enable patching - see comment on op_put_by_id.
    346346        static const int patchOffsetPutByIdStructure = 7;
    347         static const int patchOffsetPutByIdExternalLoad = 13;
    348         static const int patchLengthPutByIdExternalLoad = 3;
    349347        static const int patchOffsetPutByIdPropertyMapOffset1 = 22;
    350348        static const int patchOffsetPutByIdPropertyMapOffset2 = 28;
     
    352350        static const int patchOffsetGetByIdStructure = 7;
    353351        static const int patchOffsetGetByIdBranchToSlowCase = 13;
    354         static const int patchOffsetGetByIdExternalLoad = 13;
    355         static const int patchLengthGetByIdExternalLoad = 3;
    356352        static const int patchOffsetGetByIdPropertyMapOffset1 = 22;
    357353        static const int patchOffsetGetByIdPropertyMapOffset2 = 28;
     
    370366        // These architecture specific value are used to enable patching - see comment on op_put_by_id.
    371367        static const int patchOffsetPutByIdStructure = 4;
    372         static const int patchOffsetPutByIdExternalLoad = 16;
    373         static const int patchLengthPutByIdExternalLoad = 4;
    374368        static const int patchOffsetPutByIdPropertyMapOffset1 = 20;
    375369        static const int patchOffsetPutByIdPropertyMapOffset2 = 28;
     
    377371        static const int patchOffsetGetByIdStructure = 4;
    378372        static const int patchOffsetGetByIdBranchToSlowCase = 16;
    379         static const int patchOffsetGetByIdExternalLoad = 16;
    380         static const int patchLengthGetByIdExternalLoad = 4;
    381373        static const int patchOffsetGetByIdPropertyMapOffset1 = 20;
    382374        static const int patchOffsetGetByIdPropertyMapOffset2 = 28;
     
    411403        // These architecture specific value are used to enable patching - see comment on op_put_by_id.
    412404        static const int patchOffsetPutByIdStructure = 10;
    413         static const int patchOffsetPutByIdExternalLoad = 26;
    414         static const int patchLengthPutByIdExternalLoad = 12;
    415405        static const int patchOffsetPutByIdPropertyMapOffset1 = 46;
    416406        static const int patchOffsetPutByIdPropertyMapOffset2 = 58;
     
    418408        static const int patchOffsetGetByIdStructure = 10;
    419409        static const int patchOffsetGetByIdBranchToSlowCase = 26;
    420         static const int patchOffsetGetByIdExternalLoad = 26;
    421         static const int patchLengthGetByIdExternalLoad = 12;
    422410        static const int patchOffsetGetByIdPropertyMapOffset1 = 46;
    423411        static const int patchOffsetGetByIdPropertyMapOffset2 = 58;
     
    452440#if WTF_MIPS_ISA(1)
    453441        static const int patchOffsetPutByIdStructure = 16;
    454         static const int patchOffsetPutByIdExternalLoad = 48;
    455         static const int patchLengthPutByIdExternalLoad = 20;
    456442        static const int patchOffsetPutByIdPropertyMapOffset1 = 68;
    457443        static const int patchOffsetPutByIdPropertyMapOffset2 = 84;
    458444        static const int patchOffsetGetByIdStructure = 16;
    459445        static const int patchOffsetGetByIdBranchToSlowCase = 48;
    460         static const int patchOffsetGetByIdExternalLoad = 48;
    461         static const int patchLengthGetByIdExternalLoad = 20;
    462446        static const int patchOffsetGetByIdPropertyMapOffset1 = 68;
    463447        static const int patchOffsetGetByIdPropertyMapOffset2 = 88;
     
    474458#else // WTF_MIPS_ISA(1)
    475459        static const int patchOffsetPutByIdStructure = 12;
    476         static const int patchOffsetPutByIdExternalLoad = 44;
    477         static const int patchLengthPutByIdExternalLoad = 16;
    478460        static const int patchOffsetPutByIdPropertyMapOffset1 = 60;
    479461        static const int patchOffsetPutByIdPropertyMapOffset2 = 76;
    480462        static const int patchOffsetGetByIdStructure = 12;
    481463        static const int patchOffsetGetByIdBranchToSlowCase = 44;
    482         static const int patchOffsetGetByIdExternalLoad = 44;
    483         static const int patchLengthGetByIdExternalLoad = 16;
    484464        static const int patchOffsetGetByIdPropertyMapOffset1 = 60;
    485465        static const int patchOffsetGetByIdPropertyMapOffset2 = 76;
     
    552532#endif
    553533        void compileGetDirectOffset(RegisterID base, RegisterID result, Structure* structure, size_t cachedOffset);
    554         void compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID result, size_t cachedOffset);
    555         void compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID structure, RegisterID offset, RegisterID scratch);
     534        void compileGetDirectOffset(JSObject* base, RegisterID result, size_t cachedOffset);
     535        void compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID offset, RegisterID scratch);
    556536        void compilePutDirectOffset(RegisterID base, RegisterID value, Structure* structure, size_t cachedOffset);
    557537
     
    559539        // These architecture specific value are used to enable patching - see comment on op_put_by_id.
    560540        static const int patchOffsetPutByIdStructure = 10;
    561         static const int patchOffsetPutByIdExternalLoad = 20;
    562         static const int patchLengthPutByIdExternalLoad = 4;
    563541        static const int patchOffsetPutByIdPropertyMapOffset = 31;
    564542        // These architecture specific value are used to enable patching - see comment on op_get_by_id.
    565543        static const int patchOffsetGetByIdStructure = 10;
    566544        static const int patchOffsetGetByIdBranchToSlowCase = 20;
    567         static const int patchOffsetGetByIdExternalLoad = 20;
    568         static const int patchLengthGetByIdExternalLoad = 4;
    569545        static const int patchOffsetGetByIdPropertyMapOffset = 31;
    570546        static const int patchOffsetGetByIdPutResult = 31;
     
    582558        // These architecture specific value are used to enable patching - see comment on op_put_by_id.
    583559        static const int patchOffsetPutByIdStructure = 7;
    584         static const int patchOffsetPutByIdExternalLoad = 13;
    585         static const int patchLengthPutByIdExternalLoad = 3;
    586560        static const int patchOffsetPutByIdPropertyMapOffset = 22;
    587561        // These architecture specific value are used to enable patching - see comment on op_get_by_id.
    588562        static const int patchOffsetGetByIdStructure = 7;
    589563        static const int patchOffsetGetByIdBranchToSlowCase = 13;
    590         static const int patchOffsetGetByIdExternalLoad = 13;
    591         static const int patchLengthGetByIdExternalLoad = 3;
    592564        static const int patchOffsetGetByIdPropertyMapOffset = 22;
    593565        static const int patchOffsetGetByIdPutResult = 22;
     
    605577        // These architecture specific value are used to enable patching - see comment on op_put_by_id.
    606578        static const int patchOffsetPutByIdStructure = 10;
    607         static const int patchOffsetPutByIdExternalLoad = 26;
    608         static const int patchLengthPutByIdExternalLoad = 12;
    609579        static const int patchOffsetPutByIdPropertyMapOffset = 46;
    610580        // These architecture specific value are used to enable patching - see comment on op_get_by_id.
    611581        static const int patchOffsetGetByIdStructure = 10;
    612582        static const int patchOffsetGetByIdBranchToSlowCase = 26;
    613         static const int patchOffsetGetByIdExternalLoad = 26;
    614         static const int patchLengthGetByIdExternalLoad = 12;
    615583        static const int patchOffsetGetByIdPropertyMapOffset = 46;
    616584        static const int patchOffsetGetByIdPutResult = 50;
     
    628596        // These architecture specific value are used to enable patching - see comment on op_put_by_id.
    629597        static const int patchOffsetPutByIdStructure = 4;
    630         static const int patchOffsetPutByIdExternalLoad = 16;
    631         static const int patchLengthPutByIdExternalLoad = 4;
    632598        static const int patchOffsetPutByIdPropertyMapOffset = 20;
    633599        // These architecture specific value are used to enable patching - see comment on op_get_by_id.
    634600        static const int patchOffsetGetByIdStructure = 4;
    635601        static const int patchOffsetGetByIdBranchToSlowCase = 16;
    636         static const int patchOffsetGetByIdExternalLoad = 16;
    637         static const int patchLengthGetByIdExternalLoad = 4;
    638602        static const int patchOffsetGetByIdPropertyMapOffset = 20;
    639603        static const int patchOffsetGetByIdPutResult = 28;
     
    667631#if WTF_MIPS_ISA(1)
    668632        static const int patchOffsetPutByIdStructure = 16;
    669         static const int patchOffsetPutByIdExternalLoad = 48;
    670         static const int patchLengthPutByIdExternalLoad = 20;
    671633        static const int patchOffsetPutByIdPropertyMapOffset = 68;
    672634        static const int patchOffsetGetByIdStructure = 16;
    673635        static const int patchOffsetGetByIdBranchToSlowCase = 48;
    674         static const int patchOffsetGetByIdExternalLoad = 48;
    675         static const int patchLengthGetByIdExternalLoad = 20;
    676636        static const int patchOffsetGetByIdPropertyMapOffset = 68;
    677637        static const int patchOffsetGetByIdPutResult = 88;
     
    687647#else // WTF_MIPS_ISA(1)
    688648        static const int patchOffsetPutByIdStructure = 12;
    689         static const int patchOffsetPutByIdExternalLoad = 44;
    690         static const int patchLengthPutByIdExternalLoad = 16;
    691649        static const int patchOffsetPutByIdPropertyMapOffset = 60;
    692650        static const int patchOffsetGetByIdStructure = 12;
    693651        static const int patchOffsetGetByIdBranchToSlowCase = 44;
    694         static const int patchOffsetGetByIdExternalLoad = 44;
    695         static const int patchLengthGetByIdExternalLoad = 16;
    696652        static const int patchOffsetGetByIdPropertyMapOffset = 60;
    697653        static const int patchOffsetGetByIdPutResult = 76;
  • trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp

    r78174 r78732  
    690690    // Load cached property
    691691    // Assume that the global object always uses external storage.
    692     loadPtr(Address(regT0, OBJECT_OFFSETOF(JSGlobalObject, m_externalStorage)), regT0);
     692    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSGlobalObject, m_propertyStorage)), regT0);
    693693    load32(offsetAddr, regT1);
    694694    loadPtr(BaseIndex(regT0, regT1, ScalePtr), regT0);
  • trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp

    r75408 r78732  
    805805
    806806    // Load property.
    807     loadPtr(Address(regT0, OBJECT_OFFSETOF(JSGlobalObject, m_externalStorage)), regT2);
     807    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSGlobalObject, m_propertyStorage)), regT2);
    808808    load32(offsetAddr, regT3);
    809809    load32(BaseIndex(regT2, regT3, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0); // payload
  • trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp

    r70750 r78732  
    139139}
    140140
    141 void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID structure, RegisterID offset, RegisterID scratch)
    142 {
    143     ASSERT(sizeof(((Structure*)0)->m_propertyStorageCapacity) == sizeof(int32_t));
    144     ASSERT(sizeof(JSObject::inlineStorageCapacity) == sizeof(int32_t));
    145 
    146     Jump notUsingInlineStorage = branch32(NotEqual, Address(structure, OBJECT_OFFSETOF(Structure, m_propertyStorageCapacity)), Imm32(JSObject::inlineStorageCapacity));
    147     loadPtr(BaseIndex(base, offset, ScalePtr, OBJECT_OFFSETOF(JSObject, m_inlineStorage)), result);
    148     Jump finishedLoad = jump();
    149     notUsingInlineStorage.link(this);
    150     loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), scratch);
     141void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID offset, RegisterID scratch)
     142{
     143    loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), scratch);
    151144    loadPtr(BaseIndex(scratch, offset, ScalePtr, 0), result);
    152     finishedLoad.link(this);
    153145}
    154146
     
    173165    sub32(Imm32(1), regT3);
    174166    addSlowCase(branch32(AboveOrEqual, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_numCacheableSlots))));
    175     compileGetDirectOffset(regT0, regT0, regT2, regT3, regT1);
     167    compileGetDirectOffset(regT0, regT0, regT3, regT1);
    176168
    177169    emitPutVirtualRegister(dst, regT0);
     
    428420    ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureCheck), patchOffsetGetByIdBranchToSlowCase)
    429421
    430     Label externalLoad = loadPtrWithPatchToLEA(Address(regT0, OBJECT_OFFSETOF(JSObject, m_externalStorage)), regT0);
    431     Label externalLoadComplete(this);
    432     ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, externalLoad), patchOffsetGetByIdExternalLoad);
    433     ASSERT_JIT_OFFSET(differenceBetween(externalLoad, externalLoadComplete), patchLengthGetByIdExternalLoad);
    434 
     422    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), regT0);
    435423    DataLabel32 displacementLabel = loadPtrWithAddressOffsetPatch(Address(regT0, patchGetByIdDefaultOffset), regT0);
    436424    ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, displacementLabel), patchOffsetGetByIdPropertyMapOffset);
     
    508496    ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, structureToCompare), patchOffsetPutByIdStructure);
    509497
    510     // Plant a load from a bogus ofset in the object's property map; we will patch this later, if it is to be used.
    511     Label externalLoad = loadPtrWithPatchToLEA(Address(regT0, OBJECT_OFFSETOF(JSObject, m_externalStorage)), regT0);
    512     Label externalLoadComplete(this);
    513     ASSERT_JIT_OFFSET(differenceBetween(hotPathBegin, externalLoad), patchOffsetPutByIdExternalLoad);
    514     ASSERT_JIT_OFFSET(differenceBetween(externalLoad, externalLoadComplete), patchLengthPutByIdExternalLoad);
    515 
     498    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), regT0);
    516499    DataLabel32 displacementLabel = storePtrWithAddressOffsetPatch(regT1, Address(regT0, patchGetByIdDefaultOffset));
    517500
     
    548531    int offset = cachedOffset * sizeof(JSValue);
    549532    if (structure->isUsingInlineStorage())
    550         offset += OBJECT_OFFSETOF(JSObject, m_inlineStorage);
     533        offset += JSObject::offsetOfInlineStorage();
    551534    else
    552         loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base);
     535        loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), base);
    553536    storePtr(value, Address(base, offset));
    554537}
     
    558541{
    559542    int offset = cachedOffset * sizeof(JSValue);
    560     if (structure->isUsingInlineStorage())
    561         offset += OBJECT_OFFSETOF(JSObject, m_inlineStorage);
    562     else
    563         loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base);
    564     loadPtr(Address(base, offset), result);
    565 }
    566 
    567 void JIT::compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID result, size_t cachedOffset)
    568 {
    569     if (base->isUsingInlineStorage())
    570         loadPtr(static_cast<void*>(&base->m_inlineStorage[cachedOffset]), result);
    571     else {
    572         PropertyStorage* protoPropertyStorage = &base->m_externalStorage;
    573         loadPtr(static_cast<void*>(protoPropertyStorage), temp);
    574         loadPtr(Address(temp, cachedOffset * sizeof(JSValue)), result);
    575     }
     543    if (structure->isUsingInlineStorage()) {
     544        offset += JSObject::offsetOfInlineStorage();
     545        loadPtr(Address(base, offset), result);
     546    } else {
     547        loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), result);
     548        loadPtr(Address(result, offset), result);
     549    }
     550}
     551
     552void JIT::compileGetDirectOffset(JSObject* base, RegisterID result, size_t cachedOffset)
     553{
     554    loadPtr(static_cast<void*>(&base->m_propertyStorage[cachedOffset]), result);
    576555}
    577556
     
    669648    int offset = sizeof(JSValue) * cachedOffset;
    670649
    671     // If we're patching to use inline storage, convert the initial load to a lea; this avoids the extra load
    672     // and makes the subsequent load's offset automatically correct
    673     if (structure->isUsingInlineStorage())
    674         repatchBuffer.repatchLoadPtrToLEA(stubInfo->hotPathBegin.instructionAtOffset(patchOffsetGetByIdExternalLoad));
    675 
    676650    // Patch the offset into the propoerty map to load from, then patch the Structure to look for.
    677651    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(patchOffsetGetByIdStructure), structure);
     
    708682
    709683    int offset = sizeof(JSValue) * cachedOffset;
    710 
    711     // If we're patching to use inline storage, convert the initial load to a lea; this avoids the extra load
    712     // and makes the subsequent load's offset automatically correct
    713     if (structure->isUsingInlineStorage())
    714         repatchBuffer.repatchLoadPtrToLEA(stubInfo->hotPathBegin.instructionAtOffset(patchOffsetPutByIdExternalLoad));
    715684
    716685    // Patch the offset into the propoerty map to load from, then patch the Structure to look for.
     
    780749    if (slot.cachedPropertyType() == PropertySlot::Getter) {
    781750        needsStubLink = true;
    782         compileGetDirectOffset(protoObject, regT1, regT1, cachedOffset);
     751        compileGetDirectOffset(protoObject, regT1, cachedOffset);
    783752        JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
    784753        stubCall.addArgument(regT1);
     
    795764        stubCall.call();
    796765    } else
    797         compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
     766        compileGetDirectOffset(protoObject, regT0, cachedOffset);
    798767    Jump success = jump();
    799768    LinkBuffer patchBuffer(this, m_codeBlock->executablePool(), 0);
     
    832801    if (slot.cachedPropertyType() == PropertySlot::Getter) {
    833802        needsStubLink = true;
    834         if (!structure->isUsingInlineStorage()) {
    835             move(regT0, regT1);
    836             compileGetDirectOffset(regT1, regT1, structure, cachedOffset);
    837         } else
    838             compileGetDirectOffset(regT0, regT1, structure, cachedOffset);
     803        compileGetDirectOffset(regT0, regT1, structure, cachedOffset);
    839804        JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
    840805        stubCall.addArgument(regT1);
     
    906871    if (slot.cachedPropertyType() == PropertySlot::Getter) {
    907872        needsStubLink = true;
    908         compileGetDirectOffset(protoObject, regT1, regT1, cachedOffset);
     873        compileGetDirectOffset(protoObject, regT1, cachedOffset);
    909874        JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
    910875        stubCall.addArgument(regT1);
     
    921886        stubCall.call();
    922887    } else
    923         compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
     888        compileGetDirectOffset(protoObject, regT0, cachedOffset);
    924889
    925890    Jump success = jump();
     
    976941    if (slot.cachedPropertyType() == PropertySlot::Getter) {
    977942        needsStubLink = true;
    978         compileGetDirectOffset(protoObject, regT1, regT1, cachedOffset);
     943        compileGetDirectOffset(protoObject, regT1, cachedOffset);
    979944        JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
    980945        stubCall.addArgument(regT1);
     
    991956        stubCall.call();
    992957    } else
    993         compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
     958        compileGetDirectOffset(protoObject, regT0, cachedOffset);
    994959    Jump success = jump();
    995960
     
    10461011    if (slot.cachedPropertyType() == PropertySlot::Getter) {
    10471012        needsStubLink = true;
    1048         compileGetDirectOffset(protoObject, regT1, regT1, cachedOffset);
     1013        compileGetDirectOffset(protoObject, regT1, cachedOffset);
    10491014        JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
    10501015        stubCall.addArgument(regT1);
     
    10611026        stubCall.call();
    10621027    } else
    1063         compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
     1028        compileGetDirectOffset(protoObject, regT0, cachedOffset);
    10641029    Jump success = jump();
    10651030
  • trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp

    r70749 r78732  
    435435    ASSERT(differenceBetween(hotPathBegin, structureCheck) == patchOffsetGetByIdBranchToSlowCase);
    436436   
    437     Label externalLoad = loadPtrWithPatchToLEA(Address(regT0, OBJECT_OFFSETOF(JSObject, m_externalStorage)), regT2);
    438     Label externalLoadComplete(this);
    439     ASSERT(differenceBetween(hotPathBegin, externalLoad) == patchOffsetGetByIdExternalLoad);
    440     ASSERT(differenceBetween(externalLoad, externalLoadComplete) == patchLengthGetByIdExternalLoad);
    441    
     437    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), regT2);
    442438    DataLabel32 displacementLabel1 = loadPtrWithAddressOffsetPatch(Address(regT2, patchGetByIdDefaultOffset), regT0); // payload
    443439    ASSERT(differenceBetween(hotPathBegin, displacementLabel1) == patchOffsetGetByIdPropertyMapOffset1);
     
    513509    ASSERT(differenceBetween(hotPathBegin, structureToCompare) == patchOffsetPutByIdStructure);
    514510   
    515     // Plant a load from a bogus ofset in the object's property map; we will patch this later, if it is to be used.
    516     Label externalLoad = loadPtrWithPatchToLEA(Address(regT0, OBJECT_OFFSETOF(JSObject, m_externalStorage)), regT0);
    517     Label externalLoadComplete(this);
    518     ASSERT(differenceBetween(hotPathBegin, externalLoad) == patchOffsetPutByIdExternalLoad);
    519     ASSERT(differenceBetween(externalLoad, externalLoadComplete) == patchLengthPutByIdExternalLoad);
    520    
     511    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), regT0);
    521512    DataLabel32 displacementLabel1 = storePtrWithAddressOffsetPatch(regT2, Address(regT0, patchGetByIdDefaultOffset)); // payload
    522513    DataLabel32 displacementLabel2 = storePtrWithAddressOffsetPatch(regT3, Address(regT0, patchGetByIdDefaultOffset)); // tag
     
    553544    int offset = cachedOffset;
    554545    if (structure->isUsingInlineStorage())
    555         offset += OBJECT_OFFSETOF(JSObject, m_inlineStorage) /  sizeof(Register);
     546        offset += JSObject::offsetOfInlineStorage() /  sizeof(Register);
    556547    else
    557         loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base);
     548        loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), base);
    558549    emitStore(offset, valueTag, valuePayload, base);
    559550}
     
    563554{
    564555    int offset = cachedOffset;
    565     if (structure->isUsingInlineStorage())
    566         offset += OBJECT_OFFSETOF(JSObject, m_inlineStorage) / sizeof(Register);
    567     else
    568         loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base);
    569     emitLoad(offset, resultTag, resultPayload, base);
    570 }
    571 
    572 void JIT::compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset)
    573 {
    574     if (base->isUsingInlineStorage()) {
    575         load32(reinterpret_cast<char*>(&base->m_inlineStorage[cachedOffset]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload), resultPayload);
    576         load32(reinterpret_cast<char*>(&base->m_inlineStorage[cachedOffset]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag), resultTag);
    577         return;
     556    if (structure->isUsingInlineStorage()) {
     557        offset += JSObject::offsetOfInlineStorage() / sizeof(Register);
     558        emitLoad(offset, resultTag, resultPayload, base);
     559    } else {
     560        RegisterID temp = resultPayload;
     561        loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), temp);
     562        emitLoad(offset, resultTag, resultPayload, temp);
    578563    }
    579    
    580     size_t offset = cachedOffset * sizeof(JSValue);
    581    
    582     PropertyStorage* protoPropertyStorage = &base->m_externalStorage;
    583     loadPtr(static_cast<void*>(protoPropertyStorage), temp);
    584     load32(Address(temp, offset + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload);
    585     load32(Address(temp, offset + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag);
     564}
     565
     566void JIT::compileGetDirectOffset(JSObject* base, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset)
     567{
     568    load32(reinterpret_cast<char*>(&base->m_propertyStorage[cachedOffset]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload), resultPayload);
     569    load32(reinterpret_cast<char*>(&base->m_propertyStorage[cachedOffset]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag), resultTag);
    586570}
    587571
     
    684668   
    685669    int offset = sizeof(JSValue) * cachedOffset;
    686    
    687     // If we're patching to use inline storage, convert the initial load to a lea; this avoids the extra load
    688     // and makes the subsequent load's offset automatically correct
    689     if (structure->isUsingInlineStorage())
    690         repatchBuffer.repatchLoadPtrToLEA(stubInfo->hotPathBegin.instructionAtOffset(patchOffsetGetByIdExternalLoad));
    691    
     670
    692671    // Patch the offset into the propoerty map to load from, then patch the Structure to look for.
    693672    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(patchOffsetGetByIdStructure), structure);
     
    725704   
    726705    int offset = sizeof(JSValue) * cachedOffset;
    727    
    728     // If we're patching to use inline storage, convert the initial load to a lea; this avoids the extra load
    729     // and makes the subsequent load's offset automatically correct
    730     if (structure->isUsingInlineStorage())
    731         repatchBuffer.repatchLoadPtrToLEA(stubInfo->hotPathBegin.instructionAtOffset(patchOffsetPutByIdExternalLoad));
    732    
     706
    733707    // Patch the offset into the propoerty map to load from, then patch the Structure to look for.
    734708    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(patchOffsetPutByIdStructure), structure);
     
    800774    if (slot.cachedPropertyType() == PropertySlot::Getter) {
    801775        needsStubLink = true;
    802         compileGetDirectOffset(protoObject, regT2, regT2, regT1, cachedOffset);
     776        compileGetDirectOffset(protoObject, regT2, regT1, cachedOffset);
    803777        JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
    804778        stubCall.addArgument(regT1);
     
    815789        stubCall.call();
    816790    } else
    817         compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset);
     791        compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
    818792   
    819793    Jump success = jump();
     
    857831    if (slot.cachedPropertyType() == PropertySlot::Getter) {
    858832        needsStubLink = true;
    859         if (!structure->isUsingInlineStorage()) {
    860             move(regT0, regT1);
    861             compileGetDirectOffset(regT1, regT2, regT1, structure, cachedOffset);
    862         } else
    863             compileGetDirectOffset(regT0, regT2, regT1, structure, cachedOffset);
     833        compileGetDirectOffset(regT0, regT2, regT1, structure, cachedOffset);
    864834        JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
    865835        stubCall.addArgument(regT1);
     
    931901    if (slot.cachedPropertyType() == PropertySlot::Getter) {
    932902        needsStubLink = true;
    933         compileGetDirectOffset(protoObject, regT2, regT2, regT1, cachedOffset);
     903        compileGetDirectOffset(protoObject, regT2, regT1, cachedOffset);
    934904        JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
    935905        stubCall.addArgument(regT1);
     
    946916        stubCall.call();
    947917    } else
    948         compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset);
     918        compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
    949919   
    950920    Jump success = jump();
     
    1000970    if (slot.cachedPropertyType() == PropertySlot::Getter) {
    1001971        needsStubLink = true;
    1002         compileGetDirectOffset(protoObject, regT2, regT2, regT1, cachedOffset);
     972        compileGetDirectOffset(protoObject, regT2, regT1, cachedOffset);
    1003973        JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
    1004974        stubCall.addArgument(regT1);
     
    1015985        stubCall.call();
    1016986    } else
    1017         compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset);
     987        compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
    1018988
    1019989    Jump success = jump();
     
    10701040    if (slot.cachedPropertyType() == PropertySlot::Getter) {
    10711041        needsStubLink = true;
    1072         compileGetDirectOffset(protoObject, regT2, regT2, regT1, cachedOffset);
     1042        compileGetDirectOffset(protoObject, regT2, regT1, cachedOffset);
    10731043        JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
    10741044        stubCall.addArgument(regT1);
     
    10851055        stubCall.call();
    10861056    } else
    1087         compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset);
     1057        compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
    10881058    Jump success = jump();
    10891059   
     
    11181088#endif // !ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
    11191089
    1120 void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID structure, RegisterID offset)
    1121 {
    1122     ASSERT(sizeof(((Structure*)0)->m_propertyStorageCapacity) == sizeof(int32_t));
    1123     ASSERT(sizeof(JSObject::inlineStorageCapacity) == sizeof(int32_t));
     1090void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID offset)
     1091{
    11241092    ASSERT(sizeof(JSValue) == 8);
    11251093   
    1126     Jump notUsingInlineStorage = branch32(NotEqual, Address(structure, OBJECT_OFFSETOF(Structure, m_propertyStorageCapacity)), Imm32(JSObject::inlineStorageCapacity));
    1127     loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSObject, m_inlineStorage) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload);
    1128     loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSObject, m_inlineStorage) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag);
    1129     Jump finishedLoad = jump();
    1130     notUsingInlineStorage.link(this);
    1131     loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base);
     1094    loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_propertyStorage)), base);
    11321095    loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload);
    11331096    loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag);
    1134     finishedLoad.link(this);
    11351097}
    11361098
     
    11571119    sub32(Imm32(1), regT3);
    11581120    addSlowCase(branch32(AboveOrEqual, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_numCacheableSlots))));
    1159     compileGetDirectOffset(regT2, regT1, regT0, regT0, regT3);   
     1121    compileGetDirectOffset(regT2, regT1, regT0, regT3);   
    11601122   
    11611123    emitStore(dst, regT1, regT0);
  • trunk/Source/JavaScriptCore/jit/JITStubs.cpp

    r77151 r78732  
    11771177    else
    11781178        structure = constructor->scope().node()->globalObject->emptyObjectStructure();
    1179     JSValue result = new (&callFrame->globalData()) JSObject(structure);
     1179    JSValue result = constructEmptyObject(callFrame, structure);
    11801180
    11811181    return JSValue::encode(result);
Note: See TracChangeset for help on using the changeset viewer.