2008-12-11 Sam Weinig <sam@webkit.org>
authorweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 12 Dec 2008 08:02:09 +0000 (08:02 +0000)
committerweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 12 Dec 2008 08:02:09 +0000 (08:02 +0000)
        Reviewed by Geoffrey Garen.

        Remove dependancy on having the Instruction buffer in order to
        deref Structures used for property access and global resolves.
        Instead, we put references to the necessary Structures in axillary
        data structures on the CodeBlock. This is not an ideal solution,
        as we still pay for having the Structures in two places and we
        would like to eventually just hold on to offsets into the machine
        code buffer.

        - Also removes CodeBlock bloat in non-JIT by #ifdefing the JIT
          only data structures.

        * GNUmakefile.am:
        * JavaScriptCore.pri:
        * JavaScriptCore.scons:
        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
        * JavaScriptCore.xcodeproj/project.pbxproj:
        * JavaScriptCoreSources.bkl:
        * bytecode/CodeBlock.cpp:
        (JSC::isGlobalResolve):
        (JSC::isPropertyAccess):
        (JSC::instructionOffsetForNth):
        (JSC::printGlobalResolveInfo):
        (JSC::printStructureStubInfo):
        (JSC::CodeBlock::printStructures):
        (JSC::CodeBlock::dump):
        (JSC::CodeBlock::~CodeBlock):
        (JSC::CodeBlock::shrinkToFit):
        * bytecode/CodeBlock.h:
        (JSC::GlobalResolveInfo::GlobalResolveInfo):
        (JSC::getNativePC):
        (JSC::CodeBlock::instructions):
        (JSC::CodeBlock::getStubInfo):
        (JSC::CodeBlock::getBytecodeIndex):
        (JSC::CodeBlock::addPropertyAccessInstruction):
        (JSC::CodeBlock::addGlobalResolveInstruction):
        (JSC::CodeBlock::numberOfStructureStubInfos):
        (JSC::CodeBlock::addStructureStubInfo):
        (JSC::CodeBlock::structureStubInfo):
        (JSC::CodeBlock::addGlobalResolveInfo):
        (JSC::CodeBlock::globalResolveInfo):
        (JSC::CodeBlock::numberOfCallLinkInfos):
        (JSC::CodeBlock::addCallLinkInfo):
        (JSC::CodeBlock::callLinkInfo):
        * bytecode/Instruction.h:
        (JSC::PolymorphicAccessStructureList::PolymorphicStubInfo::set):
        (JSC::PolymorphicAccessStructureList::PolymorphicAccessStructureList):
        * bytecode/Opcode.h:
        (JSC::):
        * bytecode/StructureStubInfo.cpp: Copied from bytecode/CodeBlock.cpp.
        (JSC::StructureStubInfo::deref):
        * bytecode/StructureStubInfo.h: Copied from bytecode/CodeBlock.h.
        (JSC::StructureStubInfo::StructureStubInfo):
        (JSC::StructureStubInfo::initGetByIdSelf):
        (JSC::StructureStubInfo::initGetByIdProto):
        (JSC::StructureStubInfo::initGetByIdChain):
        (JSC::StructureStubInfo::initGetByIdSelfList):
        (JSC::StructureStubInfo::initGetByIdProtoList):
        (JSC::StructureStubInfo::initPutByIdTransition):
        (JSC::StructureStubInfo::initPutByIdReplace):
        (JSC::StructureStubInfo::):
        * bytecompiler/BytecodeGenerator.cpp:
        (JSC::BytecodeGenerator::emitResolve):
        (JSC::BytecodeGenerator::emitGetById):
        (JSC::BytecodeGenerator::emitPutById):
        (JSC::BytecodeGenerator::emitCall):
        (JSC::BytecodeGenerator::emitConstruct):
        (JSC::BytecodeGenerator::emitCatch):
        * interpreter/Interpreter.cpp:
        (JSC::Interpreter::tryCTICachePutByID):
        (JSC::Interpreter::tryCTICacheGetByID):
        (JSC::Interpreter::cti_op_get_by_id_self_fail):
        (JSC::getPolymorphicAccessStructureListSlot):
        (JSC::Interpreter::cti_op_get_by_id_proto_list):
        (JSC::Interpreter::cti_op_resolve_global):
        * jit/JIT.cpp:
        (JSC::JIT::JIT):
        (JSC::JIT::privateCompileMainPass):
        (JSC::JIT::privateCompileSlowCases):
        (JSC::JIT::privateCompile):
        * jit/JITPropertyAccess.cpp:
        (JSC::JIT::compileGetByIdHotPath):
        (JSC::JIT::compilePutByIdHotPath):
        (JSC::JIT::compileGetByIdSlowCase):
        (JSC::JIT::compilePutByIdSlowCase):
        (JSC::JIT::privateCompileGetByIdSelfList):
        (JSC::JIT::privateCompileGetByIdProtoList):
        (JSC::JIT::privateCompileGetByIdChainList):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@39229 268f45cc-cd09-0410-ab3c-d52691b4dbfc

17 files changed:
JavaScriptCore/ChangeLog
JavaScriptCore/GNUmakefile.am
JavaScriptCore/JavaScriptCore.pri
JavaScriptCore/JavaScriptCore.scons
JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
JavaScriptCore/JavaScriptCoreSources.bkl
JavaScriptCore/bytecode/CodeBlock.cpp
JavaScriptCore/bytecode/CodeBlock.h
JavaScriptCore/bytecode/Instruction.h
JavaScriptCore/bytecode/Opcode.h
JavaScriptCore/bytecode/StructureStubInfo.cpp [new file with mode: 0644]
JavaScriptCore/bytecode/StructureStubInfo.h [new file with mode: 0644]
JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
JavaScriptCore/interpreter/Interpreter.cpp
JavaScriptCore/jit/JIT.cpp
JavaScriptCore/jit/JITPropertyAccess.cpp

index 2a06483..3c06228 100644 (file)
@@ -1,3 +1,95 @@
+2008-12-11  Sam Weinig  <sam@webkit.org>
+
+        Reviewed by Geoffrey Garen.
+
+        Remove dependancy on having the Instruction buffer in order to
+        deref Structures used for property access and global resolves.
+        Instead, we put references to the necessary Structures in axillary
+        data structures on the CodeBlock. This is not an ideal solution,
+        as we still pay for having the Structures in two places and we
+        would like to eventually just hold on to offsets into the machine
+        code buffer.
+
+        - Also removes CodeBlock bloat in non-JIT by #ifdefing the JIT
+          only data structures.
+
+        * GNUmakefile.am:
+        * JavaScriptCore.pri:
+        * JavaScriptCore.scons:
+        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * JavaScriptCoreSources.bkl:
+        * bytecode/CodeBlock.cpp:
+        (JSC::isGlobalResolve):
+        (JSC::isPropertyAccess):
+        (JSC::instructionOffsetForNth):
+        (JSC::printGlobalResolveInfo):
+        (JSC::printStructureStubInfo):
+        (JSC::CodeBlock::printStructures):
+        (JSC::CodeBlock::dump):
+        (JSC::CodeBlock::~CodeBlock):
+        (JSC::CodeBlock::shrinkToFit):
+        * bytecode/CodeBlock.h:
+        (JSC::GlobalResolveInfo::GlobalResolveInfo):
+        (JSC::getNativePC):
+        (JSC::CodeBlock::instructions):
+        (JSC::CodeBlock::getStubInfo):
+        (JSC::CodeBlock::getBytecodeIndex):
+        (JSC::CodeBlock::addPropertyAccessInstruction):
+        (JSC::CodeBlock::addGlobalResolveInstruction):
+        (JSC::CodeBlock::numberOfStructureStubInfos):
+        (JSC::CodeBlock::addStructureStubInfo):
+        (JSC::CodeBlock::structureStubInfo):
+        (JSC::CodeBlock::addGlobalResolveInfo):
+        (JSC::CodeBlock::globalResolveInfo):
+        (JSC::CodeBlock::numberOfCallLinkInfos):
+        (JSC::CodeBlock::addCallLinkInfo):
+        (JSC::CodeBlock::callLinkInfo):
+        * bytecode/Instruction.h:
+        (JSC::PolymorphicAccessStructureList::PolymorphicStubInfo::set):
+        (JSC::PolymorphicAccessStructureList::PolymorphicAccessStructureList):
+        * bytecode/Opcode.h:
+        (JSC::):
+        * bytecode/StructureStubInfo.cpp: Copied from bytecode/CodeBlock.cpp.
+        (JSC::StructureStubInfo::deref):
+        * bytecode/StructureStubInfo.h: Copied from bytecode/CodeBlock.h.
+        (JSC::StructureStubInfo::StructureStubInfo):
+        (JSC::StructureStubInfo::initGetByIdSelf):
+        (JSC::StructureStubInfo::initGetByIdProto):
+        (JSC::StructureStubInfo::initGetByIdChain):
+        (JSC::StructureStubInfo::initGetByIdSelfList):
+        (JSC::StructureStubInfo::initGetByIdProtoList):
+        (JSC::StructureStubInfo::initPutByIdTransition):
+        (JSC::StructureStubInfo::initPutByIdReplace):
+        (JSC::StructureStubInfo::):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitResolve):
+        (JSC::BytecodeGenerator::emitGetById):
+        (JSC::BytecodeGenerator::emitPutById):
+        (JSC::BytecodeGenerator::emitCall):
+        (JSC::BytecodeGenerator::emitConstruct):
+        (JSC::BytecodeGenerator::emitCatch):
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::tryCTICachePutByID):
+        (JSC::Interpreter::tryCTICacheGetByID):
+        (JSC::Interpreter::cti_op_get_by_id_self_fail):
+        (JSC::getPolymorphicAccessStructureListSlot):
+        (JSC::Interpreter::cti_op_get_by_id_proto_list):
+        (JSC::Interpreter::cti_op_resolve_global):
+        * jit/JIT.cpp:
+        (JSC::JIT::JIT):
+        (JSC::JIT::privateCompileMainPass):
+        (JSC::JIT::privateCompileSlowCases):
+        (JSC::JIT::privateCompile):
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::compileGetByIdHotPath):
+        (JSC::JIT::compilePutByIdHotPath):
+        (JSC::JIT::compileGetByIdSlowCase):
+        (JSC::JIT::compilePutByIdSlowCase):
+        (JSC::JIT::privateCompileGetByIdSelfList):
+        (JSC::JIT::privateCompileGetByIdProtoList):
+        (JSC::JIT::privateCompileGetByIdChainList):
+
 2008-12-11  Gavin Barraclough  <barraclough@apple.com>
 
         Reviewed by Oliver Hunt.
index 795557f..90c591e 100644 (file)
@@ -81,6 +81,8 @@ javascriptcore_sources += \
        JavaScriptCore/jit/ExecutableAllocatorPosix.cpp \
        JavaScriptCore/jit/JIT.h \
        JavaScriptCore/jit/JITInlineMethods.h \
+       JavaScriptCore/bytecode/StructureStubInfo.cpp \
+       JavaScriptCore/bytecode/StructureStubInfo.h \
        JavaScriptCore/bytecode/CodeBlock.cpp \
        JavaScriptCore/bytecode/CodeBlock.h \
        JavaScriptCore/bytecode/JumpTable.cpp \
index af393e1..e241999 100644 (file)
@@ -69,6 +69,7 @@ SOURCES += \
     runtime/JSActivation.cpp \
     runtime/JSNotAnObject.cpp \
     bytecode/CodeBlock.cpp \
+    bytecode/StructureStubInfo.cpp \
     bytecode/JumpTable.cpp \
     jit/JIT.cpp \
     jit/JITCall.cpp \
index 78f592f..3ad2a99 100644 (file)
@@ -116,6 +116,7 @@ sources['runtime'] = [
 ]
 sources['bytecode'] = [
     'bytecode/CodeBlock.cpp',
+    'bytecode/StructureStubInfo.cpp',
     'bytecode/JumpTable.cpp',
     'bytecode/Opcode.cpp',
     'bytecode/SamplingTool.cpp',
index 4c48a05..bd87daa 100644 (file)
                        Name="bytecode"\r
                        >\r
                        <File\r
+                               RelativePath="..\..\bytecode\StructureStubInfo.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\bytecode\StructureStubInfo.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath="..\..\bytecode\CodeBlock.cpp"\r
                                >\r
                        </File>\r
index da2c5c9..48c225e 100644 (file)
                BC7F8FB90E19D1C3008632C0 /* JSNumberCell.h in Headers */ = {isa = PBXBuildFile; fileRef = BC7F8FB80E19D1C3008632C0 /* JSNumberCell.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC9041480EB9250900FE26FA /* StructureTransitionTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BC9041470EB9250900FE26FA /* StructureTransitionTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC95437D0EBA70FD0072B6D3 /* PropertyMapHashTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BC95437C0EBA70FD0072B6D3 /* PropertyMapHashTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               BCCF0D080EF0AAB900413C8F /* StructureStubInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = BCCF0D070EF0AAB900413C8F /* StructureStubInfo.h */; };
+               BCCF0D0C0EF0B8A500413C8F /* StructureStubInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCCF0D0B0EF0B8A500413C8F /* StructureStubInfo.cpp */; };
                BCD202C20E1706A7002C7E82 /* RegExpConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD202BE0E1706A7002C7E82 /* RegExpConstructor.h */; };
                BCD202C40E1706A7002C7E82 /* RegExpPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD202C00E1706A7002C7E82 /* RegExpPrototype.h */; };
                BCD202D60E170708002C7E82 /* RegExpConstructor.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BCD202D50E170708002C7E82 /* RegExpConstructor.lut.h */; };
                BC9BB95B0E19680600DF8855 /* InternalFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InternalFunction.cpp; sourceTree = "<group>"; };
                BCA62DFE0E2826230004F30D /* CallData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CallData.cpp; sourceTree = "<group>"; };
                BCA62DFF0E2826310004F30D /* ConstructData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConstructData.cpp; sourceTree = "<group>"; };
+               BCCF0D070EF0AAB900413C8F /* StructureStubInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureStubInfo.h; sourceTree = "<group>"; };
+               BCCF0D0B0EF0B8A500413C8F /* StructureStubInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructureStubInfo.cpp; sourceTree = "<group>"; };
                BCD202BD0E1706A7002C7E82 /* RegExpConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExpConstructor.cpp; sourceTree = "<group>"; };
                BCD202BE0E1706A7002C7E82 /* RegExpConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpConstructor.h; sourceTree = "<group>"; };
                BCD202BF0E1706A7002C7E82 /* RegExpPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExpPrototype.cpp; sourceTree = "<group>"; };
                                969A07950ED1D3AE00F1F681 /* Opcode.h */,
                                1429D8830ED21C3D00B89619 /* SamplingTool.cpp */,
                                1429D8840ED21C3D00B89619 /* SamplingTool.h */,
+                               BCCF0D0B0EF0B8A500413C8F /* StructureStubInfo.cpp */,
+                               BCCF0D070EF0AAB900413C8F /* StructureStubInfo.h */,
                        );
                        path = bytecode;
                        sourceTree = "<group>";
                                BC18C44D0E16F5CD00B34460 /* pcre.h in Headers */,
                                BC18C44E0E16F5CD00B34460 /* pcre_internal.h in Headers */,
                                BC18C4720E16F5CD00B34460 /* ucpinternal.h in Headers */,
+                               BCCF0D080EF0AAB900413C8F /* StructureStubInfo.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                930754D008B0F74600AB3056 /* pcre_tables.cpp in Sources */,
                                937013480CA97E0E00FA14D3 /* pcre_ucp_searchfuncs.cpp in Sources */,
                                93E26BD408B1514100F85226 /* pcre_xclass.cpp in Sources */,
+                               BCCF0D0C0EF0B8A500413C8F /* StructureStubInfo.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 4713efa..a966a19 100644 (file)
@@ -147,6 +147,7 @@ Source files for JSCore.
     </set>
     <set append="1" var="JSCORE_VM_SOURCES">
         bytecode/CodeBlock.cpp
+        bytecode/StructureStubInfo.cpp
         bytecode/JumpTable.cpp
         runtime/ExceptionHelpers.cpp
         interpreter/Interpreter.cpp
index 04e5234..cae9da3 100644 (file)
@@ -175,6 +175,103 @@ static void printPutByIdOp(int location, Vector<Instruction>::const_iterator& it
     it += 4;
 }
 
+#if ENABLE(JIT)
+static bool isGlobalResolve(OpcodeID opcodeID)
+{
+    return opcodeID == op_resolve_global;
+}
+
+static bool isPropertyAccess(OpcodeID opcodeID)
+{
+    switch (opcodeID) {
+        case op_get_by_id_self:
+        case op_get_by_id_proto:
+        case op_get_by_id_chain:
+        case op_get_by_id_self_list:
+        case op_get_by_id_proto_list:
+        case op_put_by_id_transition:
+        case op_put_by_id_replace:
+        case op_get_by_id:
+        case op_put_by_id:
+        case op_get_by_id_generic:
+        case op_put_by_id_generic:
+        case op_get_array_length:
+        case op_get_string_length:
+            return true;
+        default:
+            return false;
+    }
+}
+
+static unsigned instructionOffsetForNth(ExecState* exec, const Vector<Instruction>& instructions, int nth, bool (*predicate)(OpcodeID))
+{
+    size_t i = 0;
+    while (i < instructions.size()) {
+        OpcodeID currentOpcode = exec->interpreter()->getOpcodeID(instructions[i].u.opcode);
+        if (predicate(exec->interpreter()->getOpcodeID(instructions[i].u.opcode))) {
+            if (!--nth)
+                return i;
+        }
+        i += opcodeLengths[currentOpcode];
+    }
+
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+static void printGlobalResolveInfo(const GlobalResolveInfo& resolveInfo, unsigned instructionOffset)
+{
+    printf("  [%4d] %s: %s\n", instructionOffset, "resolve_global", pointerToSourceString(resolveInfo.structure).UTF8String().c_str());
+}
+
+static void printStructureStubInfo(const StructureStubInfo& stubInfo, unsigned instructionOffset)
+{
+    switch (stubInfo.opcodeID) {
+    case op_get_by_id_self:
+        printf("  [%4d] %s: %s\n", instructionOffset, "get_by_id_self", pointerToSourceString(stubInfo.u.getByIdSelf.baseObjectStructure).UTF8String().c_str());
+        return;
+    case op_get_by_id_proto:
+        printf("  [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(stubInfo.u.getByIdProto.baseObjectStructure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.getByIdProto.prototypeStructure).UTF8String().c_str());
+        return;
+    case op_get_by_id_chain:
+        printf("  [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(stubInfo.u.getByIdChain.baseObjectStructure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.getByIdChain.chain).UTF8String().c_str());
+        return;
+    case op_get_by_id_self_list:
+        printf("  [%4d] %s: %s (%d)\n", instructionOffset, "op_get_by_id_self_list", pointerToSourceString(stubInfo.u.getByIdSelfList.structureList).UTF8String().c_str(), stubInfo.u.getByIdSelfList.listSize);
+        return;
+    case op_get_by_id_proto_list:
+        printf("  [%4d] %s: %s (%d)\n", instructionOffset, "op_get_by_id_proto_list", pointerToSourceString(stubInfo.u.getByIdProtoList.structureList).UTF8String().c_str(), stubInfo.u.getByIdProtoList.listSize);
+        return;
+    case op_put_by_id_transition:
+        printf("  [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_transition", pointerToSourceString(stubInfo.u.putByIdTransition.previousStructure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.putByIdTransition.structure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.putByIdTransition.chain).UTF8String().c_str());
+        return;
+    case op_put_by_id_replace:
+        printf("  [%4d] %s: %s\n", instructionOffset, "put_by_id_replace", pointerToSourceString(stubInfo.u.putByIdReplace.baseObjectStructure).UTF8String().c_str());
+        return;
+    case op_get_by_id:
+        printf("  [%4d] %s\n", instructionOffset, "get_by_id");
+        return;
+    case op_put_by_id:
+        printf("  [%4d] %s\n", instructionOffset, "put_by_id");
+        return;
+    case op_get_by_id_generic:
+        printf("  [%4d] %s\n", instructionOffset, "op_get_by_id_generic");
+        return;
+    case op_put_by_id_generic:
+        printf("  [%4d] %s\n", instructionOffset, "op_put_by_id_generic");
+        return;
+    case op_get_array_length:
+        printf("  [%4d] %s\n", instructionOffset, "op_get_array_length");
+        return;
+    case op_get_string_length:
+        printf("  [%4d] %s\n", instructionOffset, "op_get_string_length");
+        return;
+    default:
+        ASSERT_NOT_REACHED();
+    }
+}
+#endif
+
 void CodeBlock::printStructure(const char* name, const Instruction* vPC, int operand) const
 {
     unsigned instructionOffset = vPC - m_instructions.begin();
@@ -199,7 +296,7 @@ void CodeBlock::printStructures(const Instruction* vPC) const
         return;
     }
     if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_transition)) {
-        printf("  [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_new", pointerToSourceString(vPC[4].u.structure).UTF8String().c_str(), pointerToSourceString(vPC[5].u.structure).UTF8String().c_str(), pointerToSourceString(vPC[6].u.structureChain).UTF8String().c_str());
+        printf("  [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_transition", pointerToSourceString(vPC[4].u.structure).UTF8String().c_str(), pointerToSourceString(vPC[5].u.structure).UTF8String().c_str(), pointerToSourceString(vPC[6].u.structureChain).UTF8String().c_str());
         return;
     }
     if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain)) {
@@ -225,19 +322,18 @@ void CodeBlock::printStructures(const Instruction* vPC) const
 
 void CodeBlock::dump(ExecState* exec) const
 {
-    Vector<Instruction>::const_iterator begin = m_instructions.begin();
-    Vector<Instruction>::const_iterator end = m_instructions.end();
-
     size_t instructionCount = 0;
-    for (Vector<Instruction>::const_iterator it = begin; it != end; ++it)
-        if (exec->interpreter()->isOpcode(it->u.opcode))
-            ++instructionCount;
+
+    for (size_t i = 0; i < m_instructions.size(); i += opcodeLengths[exec->interpreter()->getOpcodeID(m_instructions[i].u.opcode)])
+        ++instructionCount;
 
     printf("%lu m_instructions; %lu bytes at %p; %d parameter(s); %d callee register(s)\n\n",
         static_cast<unsigned long>(instructionCount),
         static_cast<unsigned long>(m_instructions.size() * sizeof(Instruction)),
         this, m_numParameters, m_numCalleeRegisters);
-    
+
+    Vector<Instruction>::const_iterator begin = m_instructions.begin();
+    Vector<Instruction>::const_iterator end = m_instructions.end();
     for (Vector<Instruction>::const_iterator it = begin; it != end; ++it)
         dump(exec, begin, it);
 
@@ -279,6 +375,25 @@ void CodeBlock::dump(ExecState* exec) const
         } while (i < m_rareData->m_regexps.size());
     }
 
+#if ENABLE(JIT)
+    if (!m_globalResolveInfos.isEmpty() || !m_structureStubInfos.isEmpty())
+        printf("\nStructures:\n");
+
+    if (!m_globalResolveInfos.isEmpty()) {
+        size_t i = 0;
+        do {
+             printGlobalResolveInfo(m_globalResolveInfos[i], instructionOffsetForNth(exec, m_instructions, i + 1, isGlobalResolve));
+             ++i;
+        } while (i < m_globalResolveInfos.size());
+    }
+    if (!m_structureStubInfos.isEmpty()) {
+        size_t i = 0;
+        do {
+            printStructureStubInfo(m_structureStubInfos[i], instructionOffsetForNth(exec, m_instructions, i + 1, isPropertyAccess));
+             ++i;
+        } while (i < m_structureStubInfos.size());
+    }
+#else
     if (!m_globalResolveInstructions.isEmpty() || !m_propertyAccessInstructions.isEmpty())
         printf("\nStructures:\n");
 
@@ -292,11 +407,12 @@ void CodeBlock::dump(ExecState* exec) const
     if (!m_propertyAccessInstructions.isEmpty()) {
         size_t i = 0;
         do {
-             printStructures(&m_instructions[m_propertyAccessInstructions[i].bytecodeIndex]);
+            printStructures(&m_instructions[m_propertyAccessInstructions[i]]);
              ++i;
         } while (i < m_propertyAccessInstructions.size());
     }
+#endif
+
     if (m_rareData && !m_rareData->m_exceptionHandlers.isEmpty()) {
         printf("\nException Handlers:\n");
         unsigned i = 0;
@@ -962,8 +1078,8 @@ static HashSet<CodeBlock*> liveCodeBlockSet;
 
 #define FOR_EACH_MEMBER_VECTOR(macro) \
     macro(instructions) \
-    macro(globalResolveInstructions) \
-    macro(propertyAccessInstructions) \
+    macro(globalResolveInfos) \
+    macro(structureStubInfos) \
     macro(callLinkInfos) \
     macro(linkedCallerList) \
     macro(identifiers) \
@@ -1074,20 +1190,27 @@ CodeBlock::CodeBlock(ScopeNode* ownerNode, CodeType codeType, PassRefPtr<SourceP
 
 CodeBlock::~CodeBlock()
 {
+#if !ENABLE(JIT)
     for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i)
         derefStructures(&m_instructions[m_globalResolveInstructions[i]]);
 
-    for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i) {
-        derefStructures(&m_instructions[m_propertyAccessInstructions[i].bytecodeIndex]);
+    for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i)
+        derefStructures(&m_instructions[m_propertyAccessInstructions[i]]);
+#else
+    for (size_t size = m_globalResolveInfos.size(), i = 0; i < size; ++i) {
+        if (m_globalResolveInfos[i].structure)
+            m_globalResolveInfos[i].structure->deref();
     }
 
+    for (size_t size = m_structureStubInfos.size(), i = 0; i < size; ++i)
+        m_structureStubInfos[i].deref();
+
     for (size_t size = m_callLinkInfos.size(), i = 0; i < size; ++i) {
         CallLinkInfo* callLinkInfo = &m_callLinkInfos[i];
         if (callLinkInfo->isLinked())
             callLinkInfo->callee->removeCaller(callLinkInfo);
     }
 
-#if ENABLE(JIT) 
     unlinkCallers();
 #endif
 
@@ -1290,12 +1413,19 @@ void CodeBlock::shrinkToFit()
 {
     m_instructions.shrinkToFit();
 
-    m_globalResolveInstructions.shrinkToFit();
+#if !ENABLE(JIT)
     m_propertyAccessInstructions.shrinkToFit();
+    m_globalResolveInstructions.shrinkToFit();
+#else
+    m_structureStubInfos.shrinkToFit();
+    m_globalResolveInfos.shrinkToFit();
     m_callLinkInfos.shrinkToFit();
     m_linkedCallerList.shrinkToFit();
+#endif
+
     m_expressionInfo.shrinkToFit();
     m_lineInfo.shrinkToFit();
+
     m_identifiers.shrinkToFit();
     m_functionExpressions.shrinkToFit();
     m_constantRegisters.shrinkToFit();
index 1f23128..1864cb6 100644 (file)
 #include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
 
+#if ENABLE(JIT)
+#include "StructureStubInfo.h"
+#endif
+
 namespace JSC {
 
     class ExecState;
@@ -53,7 +57,9 @@ namespace JSC {
         uint32_t end;
         uint32_t target;
         uint32_t scopeDepth;
+#if ENABLE(JIT)
         void* nativeCode;
+#endif
     };
 
     struct ExpressionRangeInfo {
@@ -72,21 +78,7 @@ namespace JSC {
         int32_t lineNumber;
     };
 
-    struct StructureStubInfo {
-        StructureStubInfo(unsigned bytecodeIndex)
-            : bytecodeIndex(bytecodeIndex)
-            , stubRoutine(0)
-            , callReturnLocation(0)
-            , hotPathBegin(0)
-        {
-        }
-    
-        unsigned bytecodeIndex;
-        void* stubRoutine;
-        void* callReturnLocation;
-        void* hotPathBegin;
-    };
-
+#if ENABLE(JIT)
     struct CallLinkInfo {
         CallLinkInfo()
             : callReturnLocation(0)
@@ -109,7 +101,17 @@ namespace JSC {
         bool isLinked() { return callee; }
     };
 
-#if ENABLE(JIT)
+    struct GlobalResolveInfo {
+        GlobalResolveInfo()
+            : structure(0)
+            , offset(0)
+        {
+        }
+
+        Structure* structure;
+        unsigned offset;
+    };
+
     struct PC {
         PC(void* nativePC, unsigned bytecodeIndex)
             : nativePC(nativePC)
@@ -120,7 +122,6 @@ namespace JSC {
         void* nativePC;
         unsigned bytecodeIndex;
     };
-#endif
 
     // valueAtPosition helpers for the binaryChop algorithm below.
 
@@ -134,12 +135,10 @@ namespace JSC {
         return callLinkInfo->callReturnLocation;
     }
 
-#if ENABLE(JIT)
     inline void* getNativePC(PC* pc)
     {
         return pc->nativePC;
     }
-#endif
 
     // Binary chop algorithm, calls valueAtPosition on pre-sorted elements in array,
     // compares result with key (KeyTypes should be comparable with '--', '<', '>').
@@ -176,6 +175,7 @@ namespace JSC {
         ASSERT(key == valueAtPosition(&array[0]));
         return &array[0];
     }
+#endif
 
     class CodeBlock {
         friend class JIT;
@@ -183,30 +183,20 @@ namespace JSC {
         CodeBlock(ScopeNode* ownerNode, CodeType, PassRefPtr<SourceProvider>, unsigned sourceOffset);
         ~CodeBlock();
 
-        static void dumpStatistics();
-
-#if ENABLE(JIT) 
+        void mark();
+        void refStructures(Instruction* vPC) const;
+        void derefStructures(Instruction* vPC) const;
+#if ENABLE(JIT)
         void unlinkCallers();
 #endif
 
-        void addCaller(CallLinkInfo* caller)
-        {
-            caller->callee = this;
-            caller->position = m_linkedCallerList.size();
-            m_linkedCallerList.append(caller);
-        }
-
-        void removeCaller(CallLinkInfo* caller)
-        {
-            unsigned pos = caller->position;
-            unsigned lastPos = m_linkedCallerList.size() - 1;
+        static void dumpStatistics();
 
-            if (pos != lastPos) {
-                m_linkedCallerList[pos] = m_linkedCallerList[lastPos];
-                m_linkedCallerList[pos]->position = pos;
-            }
-            m_linkedCallerList.shrink(lastPos);
-        }
+#if !defined(NDEBUG) || ENABLE_OPCODE_SAMPLING
+        void dump(ExecState*) const;
+        void printStructures(const Instruction*) const;
+        void printStructure(const char* name, const Instruction*, int operand) const;
+#endif
 
         inline bool isKnownNotImmediate(int index)
         {
@@ -234,22 +224,33 @@ namespace JSC {
             return index >= m_numVars + m_numConstants;
         }
 
-#if !defined(NDEBUG) || ENABLE_OPCODE_SAMPLING
-        void dump(ExecState*) const;
-        void printStructures(const Instruction*) const;
-        void printStructure(const char* name, const Instruction*, int operand) const;
-#endif
         int expressionRangeForVPC(const Instruction*, int& divot, int& startOffset, int& endOffset);
         int lineNumberForVPC(const Instruction* vPC);
         HandlerInfo* handlerForVPC(const Instruction* vPC);
 
-        void mark();
-        void refStructures(Instruction* vPC) const;
-        void derefStructures(Instruction* vPC) const;
+#if ENABLE(JIT)
+        void addCaller(CallLinkInfo* caller)
+        {
+            caller->callee = this;
+            caller->position = m_linkedCallerList.size();
+            m_linkedCallerList.append(caller);
+        }
+
+        void removeCaller(CallLinkInfo* caller)
+        {
+            unsigned pos = caller->position;
+            unsigned lastPos = m_linkedCallerList.size() - 1;
+
+            if (pos != lastPos) {
+                m_linkedCallerList[pos] = m_linkedCallerList[lastPos];
+                m_linkedCallerList[pos]->position = pos;
+            }
+            m_linkedCallerList.shrink(lastPos);
+        }
 
         StructureStubInfo& getStubInfo(void* returnAddress)
         {
-            return *(binaryChop<StructureStubInfo, void*, getStructureStubInfoReturnLocation>(m_propertyAccessInstructions.begin(), m_propertyAccessInstructions.size(), returnAddress));
+            return *(binaryChop<StructureStubInfo, void*, getStructureStubInfoReturnLocation>(m_structureStubInfos.begin(), m_structureStubInfos.size(), returnAddress));
         }
 
         CallLinkInfo& getCallLinkInfo(void* returnAddress)
@@ -257,7 +258,6 @@ namespace JSC {
             return *(binaryChop<CallLinkInfo, void*, getCallLinkInfoReturnLocation>(m_callLinkInfos.begin(), m_callLinkInfos.size(), returnAddress));
         }
 
-#if ENABLE(JIT)
         unsigned getBytecodeIndex(void* nativePC)
         {
             return binaryChop<PC, void*, getNativePC>(m_pcVector.begin(), m_pcVector.size(), nativePC)->bytecodeIndex;
@@ -265,6 +265,7 @@ namespace JSC {
 #endif
 
         Vector<Instruction>& instructions() { return m_instructions; }
+
 #if ENABLE(JIT)
         void setJITCode(void* jitCode) { m_jitCode = jitCode; }
         void* jitCode() { return m_jitCode; }
@@ -291,16 +292,6 @@ namespace JSC {
         SourceProvider* source() const { return m_source.get(); }
         unsigned sourceOffset() const { return m_sourceOffset; }
 
-        void addGlobalResolveInstruction(unsigned globalResolveInstructions) { m_globalResolveInstructions.append(globalResolveInstructions); }
-
-        size_t numberOfPropertyAccessInstructions() const { return m_propertyAccessInstructions.size(); }
-        void addPropertyAccessInstruction(unsigned propertyAccessInstructions) { m_propertyAccessInstructions.append(StructureStubInfo(propertyAccessInstructions)); }
-        StructureStubInfo& propertyAccessInstruction(int index) { return m_propertyAccessInstructions[index]; }
-
-        size_t numberOfCallLinkInfos() const { return m_callLinkInfos.size(); }
-        void addCallLinkInfo() { m_callLinkInfos.append(CallLinkInfo()); }
-        CallLinkInfo& callLinkInfo(int index) { return m_callLinkInfos[index]; }
-
         size_t numberOfJumpTargets() const { return m_jumpTargets.size(); }
         void addJumpTarget(unsigned jumpTarget) { m_jumpTargets.append(jumpTarget); }
         unsigned jumpTarget(int index) const { return m_jumpTargets[index]; }
@@ -316,7 +307,21 @@ namespace JSC {
         void addLineInfo(const LineInfo& lineInfo) { return m_lineInfo.append(lineInfo); }
         LineInfo& lastLineInfo() { return m_lineInfo.last(); }
 
-#if ENABLE(JIT)
+#if !ENABLE(JIT)
+        void addPropertyAccessInstruction(unsigned propertyAccessInstruction) { m_propertyAccessInstructions.append(propertyAccessInstruction); }
+        void addGlobalResolveInstruction(unsigned globalResolveInstructions) { m_globalResolveInstructions.append(globalResolveInstructions); }
+#else
+        size_t numberOfStructureStubInfos() const { return m_structureStubInfos.size(); }
+        void addStructureStubInfo(const StructureStubInfo& stubInfo) { m_structureStubInfos.append(stubInfo); }
+        StructureStubInfo& structureStubInfo(int index) { return m_structureStubInfos[index]; }
+
+        void addGlobalResolveInfo() { m_globalResolveInfos.append(GlobalResolveInfo()); }
+        GlobalResolveInfo& globalResolveInfo(int index) { return m_globalResolveInfos[index]; }
+
+        size_t numberOfCallLinkInfos() const { return m_callLinkInfos.size(); }
+        void addCallLinkInfo() { m_callLinkInfos.append(CallLinkInfo()); }
+        CallLinkInfo& callLinkInfo(int index) { return m_callLinkInfos[index]; }
+
         Vector<PC>& pcVector() { return m_pcVector; }
 #endif
 
@@ -407,10 +412,15 @@ namespace JSC {
         RefPtr<SourceProvider> m_source;
         unsigned m_sourceOffset;
 
+#if !ENABLE(JIT)
+        Vector<unsigned> m_propertyAccessInstructions;
         Vector<unsigned> m_globalResolveInstructions;
-        Vector<StructureStubInfo> m_propertyAccessInstructions;
+#else
+        Vector<StructureStubInfo> m_structureStubInfos;
+        Vector<GlobalResolveInfo> m_globalResolveInfos;
         Vector<CallLinkInfo> m_callLinkInfos;
         Vector<CallLinkInfo*> m_linkedCallerList;
+#endif
 
         Vector<unsigned> m_jumpTargets;
 
index ed9ba72..81a7fa0 100644 (file)
@@ -30,6 +30,7 @@
 #define Instruction_h
 
 #include "Opcode.h"
+#include "Structure.h"
 #include <wtf/VectorTraits.h>
 
 #define POLYMORPHIC_LIST_CACHE_SIZE 4
@@ -40,11 +41,10 @@ namespace JSC {
     class Structure;
     class StructureChain;
 
-    // Structure used by op_get_by_id_proto_list instruction to hold data off the main opcode stream.
+    // Structure used by op_get_by_id_self_list and op_get_by_id_proto_list instruction to hold data off the main opcode stream.
     struct PolymorphicAccessStructureList {
         struct PolymorphicStubInfo {
-            unsigned cachedOffset : 31;
-            unsigned isChain : 1;
+            bool isChain;
             void* stubRoutine;
             Structure* base;
             union {
@@ -52,27 +52,24 @@ namespace JSC {
                 StructureChain* chain;
             } u;
 
-            void set(int _cachedOffset, void* _stubRoutine, Structure* _base)
+            void set(void* _stubRoutine, Structure* _base)
             {
-                cachedOffset = _cachedOffset;
                 stubRoutine = _stubRoutine;
                 base = _base;
                 u.proto = 0;
                 isChain = false;
             }
             
-            void set(int _cachedOffset, void* _stubRoutine, Structure* _base, Structure* _proto)
+            void set(void* _stubRoutine, Structure* _base, Structure* _proto)
             {
-                cachedOffset = _cachedOffset;
                 stubRoutine = _stubRoutine;
                 base = _base;
                 u.proto = _proto;
                 isChain = false;
             }
             
-            void set(int _cachedOffset, void* _stubRoutine, Structure* _base, StructureChain* _chain)
+            void set(void* _stubRoutine, Structure* _base, StructureChain* _chain)
             {
-                cachedOffset = _cachedOffset;
                 stubRoutine = _stubRoutine;
                 base = _base;
                 u.chain = _chain;
@@ -80,19 +77,19 @@ namespace JSC {
             }
         } list[POLYMORPHIC_LIST_CACHE_SIZE];
         
-        PolymorphicAccessStructureList(int cachedOffset, void* stubRoutine, Structure* firstBase)
+        PolymorphicAccessStructureList(void* stubRoutine, Structure* firstBase)
         {
-            list[0].set(cachedOffset, stubRoutine, firstBase);
+            list[0].set(stubRoutine, firstBase);
         }
 
-        PolymorphicAccessStructureList(int cachedOffset, void* stubRoutine, Structure* firstBase, Structure* firstProto)
+        PolymorphicAccessStructureList(void* stubRoutine, Structure* firstBase, Structure* firstProto)
         {
-            list[0].set(cachedOffset, stubRoutine, firstBase, firstProto);
+            list[0].set(stubRoutine, firstBase, firstProto);
         }
 
-        PolymorphicAccessStructureList(int cachedOffset, void* stubRoutine, Structure* firstBase, StructureChain* firstChain)
+        PolymorphicAccessStructureList(void* stubRoutine, Structure* firstBase, StructureChain* firstChain)
         {
-            list[0].set(cachedOffset, stubRoutine, firstBase, firstChain);
+            list[0].set(stubRoutine, firstBase, firstChain);
         }
 
         void derefStructures(int count)
index aaaac8d..bfa37a3 100644 (file)
@@ -178,6 +178,10 @@ namespace JSC {
     
     #define OPCODE_LENGTH(opcode) opcode##_length
 
+    #define OPCODE_ID_LENGTH_MAP(opcode, length) length,
+        const int opcodeLengths[numOpcodeIDs] = { FOR_EACH_OPCODE_ID(OPCODE_ID_LENGTH_MAP) };
+    #undef OPCODE_ID_LENGTH_MAP
+
     #define VERIFY_OPCODE_ID(id, size) COMPILE_ASSERT(id <= op_end, ASSERT_THAT_JS_OPCODE_IDS_ARE_VALID);
         FOR_EACH_OPCODE_ID(VERIFY_OPCODE_ID);
     #undef VERIFY_OPCODE_ID
diff --git a/JavaScriptCore/bytecode/StructureStubInfo.cpp b/JavaScriptCore/bytecode/StructureStubInfo.cpp
new file mode 100644 (file)
index 0000000..bf3fdc4
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "StructureStubInfo.h"
+
+namespace JSC {
+
+#if ENABLE(JIT)
+void StructureStubInfo::deref()
+{
+    switch (opcodeID) {
+    case op_get_by_id_self:
+        u.getByIdSelf.baseObjectStructure->deref();
+        return;
+    case op_get_by_id_proto:
+        u.getByIdProto.baseObjectStructure->deref();
+        u.getByIdProto.prototypeStructure->deref();
+        return;
+    case op_get_by_id_chain:
+        u.getByIdChain.baseObjectStructure->deref();
+        u.getByIdChain.chain->deref();
+        return;
+    case op_get_by_id_self_list: {
+        PolymorphicAccessStructureList* polymorphicStructures = u.getByIdSelfList.structureList;
+        polymorphicStructures->derefStructures(u.getByIdSelfList.listSize);
+        delete polymorphicStructures;
+        return;
+    }
+    case op_get_by_id_proto_list: {
+        PolymorphicAccessStructureList* polymorphicStructures = u.getByIdProtoList.structureList;
+        polymorphicStructures->derefStructures(u.getByIdProtoList.listSize);
+        delete polymorphicStructures;
+        return;
+    }
+    case op_put_by_id_transition:
+        u.putByIdTransition.previousStructure->deref();
+        u.putByIdTransition.structure->deref();
+        u.putByIdTransition.chain->deref();
+        return;
+    case op_put_by_id_replace:
+        u.putByIdReplace.baseObjectStructure->deref();
+        return;
+    case op_get_by_id:
+    case op_put_by_id:
+    case op_get_by_id_generic:
+    case op_put_by_id_generic:
+    case op_get_array_length:
+    case op_get_string_length:
+        // These instructions don't ref their Structures.
+        return;
+    default:
+        ASSERT_NOT_REACHED();
+    }
+}
+#endif
+
+} // namespace JSC
diff --git a/JavaScriptCore/bytecode/StructureStubInfo.h b/JavaScriptCore/bytecode/StructureStubInfo.h
new file mode 100644 (file)
index 0000000..a9e0678
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef StructureStubInfo_h
+#define StructureStubInfo_h
+
+#include "Instruction.h"
+#include "Opcode.h"
+#include "Structure.h"
+
+namespace JSC {
+
+#if ENABLE(JIT)
+    struct StructureStubInfo {
+        StructureStubInfo(OpcodeID opcodeID)
+            : opcodeID(opcodeID)
+            , stubRoutine(0)
+            , callReturnLocation(0)
+            , hotPathBegin(0)
+        {
+        }
+
+        void initGetByIdSelf(Structure* baseObjectStructure)
+        {
+            opcodeID = op_get_by_id_self;
+
+            u.getByIdSelf.baseObjectStructure = baseObjectStructure;
+            baseObjectStructure->ref();
+        }
+
+        void initGetByIdProto(Structure* baseObjectStructure, Structure* prototypeStructure)
+        {
+            opcodeID = op_get_by_id_proto;
+
+            u.getByIdProto.baseObjectStructure = baseObjectStructure;
+            baseObjectStructure->ref();
+
+            u.getByIdProto.prototypeStructure = prototypeStructure;
+            prototypeStructure->ref();
+        }
+
+        void initGetByIdChain(Structure* baseObjectStructure, StructureChain* chain)
+        {
+            opcodeID = op_get_by_id_chain;
+
+            u.getByIdChain.baseObjectStructure = baseObjectStructure;
+            baseObjectStructure->ref();
+
+            u.getByIdChain.chain = chain;
+            chain->ref();
+        }
+
+        void initGetByIdSelfList(PolymorphicAccessStructureList* structureList, int listSize)
+        {
+            opcodeID = op_get_by_id_self_list;
+
+            u.getByIdProtoList.structureList = structureList;
+            u.getByIdProtoList.listSize = listSize;
+        }
+
+        void initGetByIdProtoList(PolymorphicAccessStructureList* structureList, int listSize)
+        {
+            opcodeID = op_get_by_id_proto_list;
+
+            u.getByIdProtoList.structureList = structureList;
+            u.getByIdProtoList.listSize = listSize;
+        }
+
+        // PutById*
+
+        void initPutByIdTransition(Structure* previousStructure, Structure* structure, StructureChain* chain)
+        {
+            opcodeID = op_put_by_id_transition;
+
+            u.putByIdTransition.previousStructure = previousStructure;
+            previousStructure->ref();
+
+            u.putByIdTransition.structure = structure;
+            structure->ref();
+
+            u.putByIdTransition.chain = chain;
+            chain->ref();
+        }
+
+        void initPutByIdReplace(Structure* baseObjectStructure)
+        {
+            opcodeID = op_put_by_id_replace;
+    
+            u.putByIdReplace.baseObjectStructure = baseObjectStructure;
+            baseObjectStructure->ref();
+        }
+
+        void deref();
+
+        OpcodeID opcodeID;
+        union {
+            struct {
+                Structure* baseObjectStructure;
+            } getByIdSelf;
+            struct {
+                Structure* baseObjectStructure;
+                Structure* prototypeStructure;
+            } getByIdProto;
+            struct {
+                Structure* baseObjectStructure;
+                StructureChain* chain;
+            } getByIdChain;
+            struct {
+                PolymorphicAccessStructureList* structureList;
+                int listSize;
+            } getByIdSelfList;
+            struct {
+                PolymorphicAccessStructureList* structureList;
+                int listSize;
+            } getByIdProtoList;
+            struct {
+                Structure* previousStructure;
+                Structure* structure;
+                StructureChain* chain;
+            } putByIdTransition;
+            struct {
+                Structure* baseObjectStructure;
+            } putByIdReplace;
+        } u;
+
+        void* stubRoutine;
+        void* callReturnLocation;
+        void* hotPathBegin;
+    };
+#endif
+
+} // namespace JSC
+
+#endif // StructureStubInfo_h
index 3eaa664..f7b0240 100644 (file)
@@ -980,7 +980,11 @@ RegisterID* BytecodeGenerator::emitResolve(RegisterID* dst, const Identifier& pr
     }
 
     if (globalObject) {
+#if ENABLE(JIT)
+        m_codeBlock->addGlobalResolveInfo();
+#else
         m_codeBlock->addGlobalResolveInstruction(instructions().size());
+#endif
         emitOpcode(op_resolve_global);
         instructions().append(dst->index());
         instructions().append(globalObject);
@@ -1060,7 +1064,11 @@ RegisterID* BytecodeGenerator::emitResolveFunction(RegisterID* baseDst, Register
 
 RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
 {
+#if ENABLE(JIT)
+    m_codeBlock->addStructureStubInfo(StructureStubInfo(op_get_by_id));
+#else
     m_codeBlock->addPropertyAccessInstruction(instructions().size());
+#endif
 
     emitOpcode(op_get_by_id);
     instructions().append(dst->index());
@@ -1075,7 +1083,11 @@ RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, co
 
 RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
 {
+#if ENABLE(JIT)
+    m_codeBlock->addStructureStubInfo(StructureStubInfo(op_put_by_id));
+#else
     m_codeBlock->addPropertyAccessInstruction(instructions().size());
+#endif
 
     emitOpcode(op_put_by_id);
     instructions().append(base->index());
@@ -1247,7 +1259,10 @@ RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, Regi
     }
 
     emitExpressionInfo(divot, startOffset, endOffset);
+
+#if ENABLE(JIT)
     m_codeBlock->addCallLinkInfo();
+#endif
 
     // Emit call.
     emitOpcode(opcodeID);
@@ -1326,7 +1341,10 @@ RegisterID* BytecodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func,
         callFrame.append(newTemporary());
 
     emitExpressionInfo(divot, startOffset, endOffset);
+
+#if ENABLE(JIT)
     m_codeBlock->addCallLinkInfo();
+#endif
 
     emitOpcode(op_construct);
     instructions().append(dst->index()); // dst
@@ -1544,7 +1562,12 @@ RegisterID* BytecodeGenerator::emitNextPropertyName(RegisterID* dst, RegisterID*
 
 RegisterID* BytecodeGenerator::emitCatch(RegisterID* targetRegister, Label* start, Label* end)
 {
+#if ENABLE(JIT)
     HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth, 0 };
+#else
+    HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth };
+#endif
+
     m_codeBlock->addExceptionHandler(info);
     emitOpcode(op_catch);
     instructions().append(targetRegister->index());
index 5be588c..3270329 100644 (file)
@@ -4086,35 +4086,26 @@ NEVER_INLINE void Interpreter::tryCTICachePutByID(CallFrame* callFrame, CodeBloc
     }
 
     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(returnAddress);
-    Instruction* vPC = codeBlock->instructions().begin() + stubInfo->bytecodeIndex;
 
     // Cache hit: Specialize instruction and ref Structures.
 
     // Structure transition, cache transition info
     if (slot.type() == PutPropertySlot::NewProperty) {
-        vPC[0] = getOpcode(op_put_by_id_transition);
-        vPC[4] = structure->previousID();
-        vPC[5] = structure;
         StructureChain* chain = structure->cachedPrototypeChain();
         if (!chain) {
             chain = cachePrototypeChain(callFrame, structure);
             if (!chain) {
-                // This happens if someone has manually inserted null into the prototype chain
-                vPC[0] = getOpcode(op_put_by_id_generic);
+                // This happens if someone has manually inserted null into the prototype chain 
+                stubInfo->opcodeID = op_put_by_id_generic;
                 return;
             }
         }
-        vPC[6] = chain;
-        vPC[7] = slot.cachedOffset();
-        codeBlock->refStructures(vPC);
+        stubInfo->initPutByIdTransition(structure->previousID(), structure, chain);
         JIT::compilePutByIdTransition(callFrame->scopeChain()->globalData, codeBlock, stubInfo, structure->previousID(), structure, slot.cachedOffset(), chain, returnAddress);
         return;
     }
     
-    vPC[0] = getOpcode(op_put_by_id_replace);
-    vPC[4] = structure;
-    vPC[5] = slot.cachedOffset();
-    codeBlock->refStructures(vPC);
+    stubInfo->initPutByIdReplace(structure);
 
 #if USE(CTI_REPATCH_PIC)
     UNUSED_PARAM(callFrame);
@@ -4168,16 +4159,12 @@ NEVER_INLINE void Interpreter::tryCTICacheGetByID(CallFrame* callFrame, CodeBloc
     // *_second method to achieve a similar (but not quite the same) effect.
 
     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(returnAddress);
-    Instruction* vPC = codeBlock->instructions().begin() + stubInfo->bytecodeIndex;
 
     // Cache hit: Specialize instruction and ref Structures.
 
     if (slot.slotBase() == baseValue) {
         // set this up, so derefStructures can do it's job.
-        vPC[0] = getOpcode(op_get_by_id_self);
-        vPC[4] = structure;
-        vPC[5] = slot.cachedOffset();
-        codeBlock->refStructures(vPC);
+        stubInfo->initGetByIdSelf(structure);
         
 #if USE(CTI_REPATCH_PIC)
         JIT::patchGetByIdSelf(stubInfo, structure, slot.cachedOffset(), returnAddress);
@@ -4199,12 +4186,8 @@ NEVER_INLINE void Interpreter::tryCTICacheGetByID(CallFrame* callFrame, CodeBloc
             slotBaseObject->setStructure(transition.release());
             asObject(baseValue)->structure()->setCachedPrototypeChain(0);
         }
-
-        vPC[0] = getOpcode(op_get_by_id_proto);
-        vPC[4] = structure;
-        vPC[5] = slotBaseObject->structure();
-        vPC[6] = slot.cachedOffset();
-        codeBlock->refStructures(vPC);
+        
+        stubInfo->initGetByIdProto(structure, slotBaseObject->structure());
 
         JIT::compileGetByIdProto(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, slotBaseObject->structure(), slot.cachedOffset(), returnAddress);
         return;
@@ -4212,7 +4195,7 @@ NEVER_INLINE void Interpreter::tryCTICacheGetByID(CallFrame* callFrame, CodeBloc
 
     size_t count = countPrototypeChainEntriesAndCheckForProxies(callFrame, baseValue, slot);
     if (!count) {
-        vPC[0] = getOpcode(op_get_by_id_generic);
+        stubInfo->opcodeID = op_get_by_id_generic;
         return;
     }
 
@@ -4221,12 +4204,7 @@ NEVER_INLINE void Interpreter::tryCTICacheGetByID(CallFrame* callFrame, CodeBloc
         chain = cachePrototypeChain(callFrame, structure);
     ASSERT(chain);
 
-    vPC[0] = getOpcode(op_get_by_id_chain);
-    vPC[4] = structure;
-    vPC[5] = chain;
-    vPC[6] = count;
-    vPC[7] = slot.cachedOffset();
-    codeBlock->refStructures(vPC);
+    stubInfo->initGetByIdChain(structure, chain);
 
     JIT::compileGetByIdChain(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, chain, count, slot.cachedOffset(), returnAddress);
 }
@@ -4575,25 +4553,20 @@ JSValue* Interpreter::cti_op_get_by_id_self_fail(CTI_ARGS)
 
         CodeBlock* codeBlock = callFrame->codeBlock();
         StructureStubInfo* stubInfo = &codeBlock->getStubInfo(CTI_RETURN_ADDRESS);
-        Instruction* vPC = codeBlock->instructions().begin() + stubInfo->bytecodeIndex;
 
         ASSERT(slot.slotBase()->isObject());
 
         PolymorphicAccessStructureList* polymorphicStructureList;
         int listIndex = 1;
 
-        if (vPC[0].u.opcode == ARG_globalData->interpreter->getOpcode(op_get_by_id_self)) {
+        if (stubInfo->opcodeID == op_get_by_id_self) {
             ASSERT(!stubInfo->stubRoutine);
-            polymorphicStructureList = new PolymorphicAccessStructureList(vPC[5].u.operand, 0, vPC[4].u.structure);
-
-            vPC[0] = ARG_globalData->interpreter->getOpcode(op_get_by_id_self_list);
-            vPC[4] = polymorphicStructureList;
-            vPC[5] = 2;
+            polymorphicStructureList = new PolymorphicAccessStructureList(0, stubInfo->u.getByIdSelf.baseObjectStructure);
+            stubInfo->initGetByIdSelfList(polymorphicStructureList, 2);
         } else {
-            polymorphicStructureList = vPC[4].u.polymorphicStructures;
-            listIndex = vPC[5].u.operand;
-
-            vPC[5] = listIndex + 1;
+            polymorphicStructureList = stubInfo->u.getByIdSelfList.structureList;
+            listIndex = stubInfo->u.getByIdSelfList.listSize;
+            stubInfo->u.getByIdSelfList.listSize++;
         }
 
         JIT::compileGetByIdSelfList(callFrame->scopeChain()->globalData, codeBlock, stubInfo, polymorphicStructureList, listIndex, asCell(baseValue)->structure(), slot.cachedOffset());
@@ -4606,34 +4579,32 @@ JSValue* Interpreter::cti_op_get_by_id_self_fail(CTI_ARGS)
     return result;
 }
 
-static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(Interpreter* interpreter, StructureStubInfo* stubInfo, Instruction* vPC, int& listIndex)
+static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(StructureStubInfo* stubInfo, int& listIndex)
 {
-    PolymorphicAccessStructureList* prototypeStructureList;
+    PolymorphicAccessStructureList* prototypeStructureList = 0;
     listIndex = 1;
 
-    if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto)) {
-        prototypeStructureList = new PolymorphicAccessStructureList(vPC[6].u.operand, stubInfo->stubRoutine, vPC[4].u.structure, vPC[5].u.structure);
+    switch (stubInfo->opcodeID) {
+    case op_get_by_id_proto:
+        prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure, stubInfo->u.getByIdProto.prototypeStructure);
         stubInfo->stubRoutine = 0;
-
-        vPC[0] = interpreter->getOpcode(op_get_by_id_proto_list);
-        vPC[4] = prototypeStructureList;
-        vPC[5] = 2;
-    } else if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain)) {
-        prototypeStructureList = new PolymorphicAccessStructureList(vPC[6].u.operand, stubInfo->stubRoutine, vPC[4].u.structure, vPC[5].u.structureChain);
+        stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
+        break;
+    case op_get_by_id_chain:
+        prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure, stubInfo->u.getByIdChain.chain);
         stubInfo->stubRoutine = 0;
-
-        vPC[0] = interpreter->getOpcode(op_get_by_id_proto_list);
-        vPC[4] = prototypeStructureList;
-        vPC[5] = 2;
-    } else {
-        ASSERT(vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto_list));
-        prototypeStructureList = vPC[4].u.polymorphicStructures;
-        listIndex = vPC[5].u.operand;
-        vPC[5] = listIndex + 1;
-
-        ASSERT(listIndex < POLYMORPHIC_LIST_CACHE_SIZE);
+        stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
+        break;
+    case op_get_by_id_proto_list:
+        prototypeStructureList = stubInfo->u.getByIdProtoList.structureList;
+        listIndex = stubInfo->u.getByIdProtoList.listSize;
+        stubInfo->u.getByIdProtoList.listSize++;
+        break;
+    default:
+        ASSERT_NOT_REACHED();
     }
     
+    ASSERT(listIndex < POLYMORPHIC_LIST_CACHE_SIZE);
     return prototypeStructureList;
 }
 
@@ -4657,7 +4628,6 @@ JSValue* Interpreter::cti_op_get_by_id_proto_list(CTI_ARGS)
     Structure* structure = asCell(baseValue)->structure();
     CodeBlock* codeBlock = callFrame->codeBlock();
     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(CTI_RETURN_ADDRESS);
-    Instruction* vPC = codeBlock->instructions().begin() + stubInfo->bytecodeIndex;
 
     ASSERT(slot.slotBase()->isObject());
     JSObject* slotBaseObject = asObject(slot.slotBase());
@@ -4674,7 +4644,7 @@ JSValue* Interpreter::cti_op_get_by_id_proto_list(CTI_ARGS)
         }
 
         int listIndex;
-        PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(ARG_globalData->interpreter, stubInfo, vPC, listIndex);
+        PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
 
         JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), slot.cachedOffset());
 
@@ -4687,7 +4657,7 @@ JSValue* Interpreter::cti_op_get_by_id_proto_list(CTI_ARGS)
         ASSERT(chain);
 
         int listIndex;
-        PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(ARG_globalData->interpreter, stubInfo, vPC, listIndex);
+        PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
 
         JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, chain, count, slot.cachedOffset());
 
@@ -5357,18 +5327,20 @@ JSValue* Interpreter::cti_op_resolve_global(CTI_ARGS)
     CallFrame* callFrame = ARG_callFrame;
     JSGlobalObject* globalObject = asGlobalObject(ARG_src1);
     Identifier& ident = *ARG_id2;
-    Instruction* vPC = ARG_instr3;
+    unsigned globalResolveInfoIndex = ARG_int3;
+    Instruction* vPC = ARG_instr4;
     ASSERT(globalObject->isGlobalObject());
 
     PropertySlot slot(globalObject);
     if (globalObject->getPropertySlot(callFrame, ident, slot)) {
         JSValue* result = slot.getValue(callFrame, ident);
         if (slot.isCacheable()) {
-            if (vPC[4].u.structure)
-                vPC[4].u.structure->deref();
+            GlobalResolveInfo& globalResolveInfo = callFrame->codeBlock()->globalResolveInfo(globalResolveInfoIndex);
+            if (globalResolveInfo.structure)
+                globalResolveInfo.structure->deref();
             globalObject->structure()->ref();
-            vPC[4] = globalObject->structure();
-            vPC[5] = slot.cachedOffset();
+            globalResolveInfo.structure = globalObject->structure();
+            globalResolveInfo.offset = slot.cachedOffset();
             return result;
         }
 
index 2f71925..b81daa0 100644 (file)
@@ -176,7 +176,7 @@ JIT::JIT(JSGlobalData* globalData, CodeBlock* codeBlock)
     , m_globalData(globalData)
     , m_codeBlock(codeBlock)
     , m_labels(codeBlock ? codeBlock->instructions().size() : 0)
-    , m_propertyAccessCompilationInfo(codeBlock ? codeBlock->numberOfPropertyAccessInstructions() : 0)
+    , m_propertyAccessCompilationInfo(codeBlock ? codeBlock->numberOfStructureStubInfos() : 0)
     , m_callStructureStubCompilationInfo(codeBlock ? codeBlock->numberOfCallLinkInfos() : 0)
     , m_lastResultBytecodeRegister(std::numeric_limits<int>::max())
     , m_jumpTargetsPosition(0)
@@ -260,6 +260,7 @@ void JIT::privateCompileMainPass()
     unsigned instructionCount = m_codeBlock->instructions().size();
 
     unsigned propertyAccessInstructionIndex = 0;
+    unsigned globalResolveInfoIndex = 0;
     unsigned callLinkInfoIndex = 0;
 
     for (unsigned i = 0; i < instructionCount; ) {
@@ -698,8 +699,10 @@ void JIT::privateCompileMainPass()
             // Fast case
             void* globalObject = instruction[i + 2].u.jsCell;
             Identifier* ident = &(m_codeBlock->identifier(instruction[i + 3].u.operand));
-            void* structureAddress = reinterpret_cast<void*>(instruction + i + 4);
-            void* offsetAddr = reinterpret_cast<void*>(instruction + i + 5);
+            
+            unsigned currentIndex = globalResolveInfoIndex++;
+            void* structureAddress = &(m_codeBlock->globalResolveInfo(currentIndex).structure);
+            void* offsetAddr = &(m_codeBlock->globalResolveInfo(currentIndex).offset);
 
             // Check Structure of global object
             move(ImmPtr(globalObject), X86::eax);
@@ -717,7 +720,8 @@ void JIT::privateCompileMainPass()
             noMatch.link(this);
             emitPutCTIArgConstant(globalObject, 0);
             emitPutCTIArgConstant(reinterpret_cast<unsigned>(ident), 4);
-            emitPutCTIArgConstant(reinterpret_cast<unsigned>(instruction + i), 8);
+            emitPutCTIArgConstant(currentIndex, 8);
+            emitPutCTIArgConstant(reinterpret_cast<unsigned>(instruction + i), 12);
             emitCTICall(i, Interpreter::cti_op_resolve_global);
             emitPutVirtualRegister(instruction[i + 1].u.operand);
             end.link(this);
@@ -1349,7 +1353,7 @@ void JIT::privateCompileMainPass()
         }
     }
 
-    ASSERT(propertyAccessInstructionIndex == m_codeBlock->numberOfPropertyAccessInstructions());
+    ASSERT(propertyAccessInstructionIndex == m_codeBlock->numberOfStructureStubInfos());
     ASSERT(callLinkInfoIndex == m_codeBlock->numberOfCallLinkInfos());
 }
 
@@ -1873,7 +1877,7 @@ void JIT::privateCompileSlowCases()
         __ link(__ jmp(), m_labels[i]);
     }
 
-    ASSERT(propertyAccessInstructionIndex == m_codeBlock->numberOfPropertyAccessInstructions());
+    ASSERT(propertyAccessInstructionIndex == m_codeBlock->numberOfStructureStubInfos());
     ASSERT(callLinkInfoIndex == m_codeBlock->numberOfCallLinkInfos());
 }
 
@@ -1964,8 +1968,8 @@ void JIT::privateCompile()
     for (Vector<JSRInfo>::iterator iter = m_jsrSites.begin(); iter != m_jsrSites.end(); ++iter)
         X86Assembler::linkAbsoluteAddress(code, iter->addrPosition, iter->target);
 
-    for (unsigned i = 0; i < m_codeBlock->numberOfPropertyAccessInstructions(); ++i) {
-        StructureStubInfo& info = m_codeBlock->propertyAccessInstruction(i);
+    for (unsigned i = 0; i < m_codeBlock->numberOfStructureStubInfos(); ++i) {
+        StructureStubInfo& info = m_codeBlock->structureStubInfo(i);
         info.callReturnLocation = X86Assembler::getRelocatedAddress(code, m_propertyAccessCompilationInfo[i].callReturnLocation);
         info.hotPathBegin = X86Assembler::getRelocatedAddress(code, m_propertyAccessCompilationInfo[i].hotPathBegin);
     }
index 50487d1..65ad1f4 100644 (file)
@@ -58,7 +58,6 @@ void JIT::compileGetByIdHotPath(int resultVReg, int baseVReg, Identifier* ident,
 #ifdef NDEBUG
     UNUSED_PARAM(propertyAccessInstructionIndex);
 #endif
-    ASSERT(m_codeBlock->propertyAccessInstruction(propertyAccessInstructionIndex).bytecodeIndex == i);
 
 #ifndef NDEBUG
     JmpDst coldPathBegin = __ label();
@@ -70,7 +69,6 @@ void JIT::compileGetByIdHotPath(int resultVReg, int baseVReg, Identifier* ident,
     emitPutVirtualRegister(resultVReg);
 
     // Track the location of the call; this will be used to recover repatch information.
-    ASSERT(m_codeBlock->propertyAccessInstruction(propertyAccessInstructionIndex).bytecodeIndex == i);
     m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].callReturnLocation = call;
 }
 
@@ -94,7 +92,6 @@ void JIT::compilePutByIdHotPath(int baseVReg, Identifier* ident, int valueVReg,
     JmpSrc call = emitCTICall(i, Interpreter::cti_op_put_by_id_generic);
 
     // Track the location of the call; this will be used to recover repatch information.
-    ASSERT(m_codeBlock->propertyAccessInstruction(propertyAccessInstructionIndex).bytecodeIndex == i);
     m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].callReturnLocation = call;
 }
 
@@ -114,8 +111,6 @@ void JIT::compileGetByIdHotPath(int resultVReg, int baseVReg, Identifier*, unsig
 
     emitGetVirtualRegister(baseVReg, X86::eax, i);
 
-    ASSERT(m_codeBlock->propertyAccessInstruction(propertyAccessInstructionIndex).bytecodeIndex == i);
-
     emitJumpSlowCaseIfNotJSCell(X86::eax, i, baseVReg);
 
     JmpDst hotPathBegin = __ label();
@@ -155,7 +150,6 @@ void JIT::compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident
     emitPutVirtualRegister(resultVReg);
 
     // Track the location of the call; this will be used to recover repatch information.
-    ASSERT(m_codeBlock->propertyAccessInstruction(propertyAccessInstructionIndex).bytecodeIndex == i);
     m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].callReturnLocation = call;
 }
 
@@ -167,8 +161,6 @@ void JIT::compilePutByIdHotPath(int baseVReg, Identifier*, int valueVReg, unsign
 
     emitGetVirtualRegisters(baseVReg, X86::eax, valueVReg, X86::edx, i);
 
-    ASSERT(m_codeBlock->propertyAccessInstruction(propertyAccessInstructionIndex).bytecodeIndex == i);
-
     // Jump to a slow case if either the base object is an immediate, or if the Structure does not match.
     emitJumpSlowCaseIfNotJSCell(X86::eax, i, baseVReg);
 
@@ -198,7 +190,6 @@ void JIT::compilePutByIdSlowCase(int baseVReg, Identifier* ident, int, unsigned
     JmpSrc call = emitCTICall(i, Interpreter::cti_op_put_by_id);
 
     // Track the location of the call; this will be used to recover repatch information.
-    ASSERT(m_codeBlock->propertyAccessInstruction(propertyAccessInstructionIndex).bytecodeIndex == i);
     m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].callReturnLocation = call;
 }
 
@@ -482,7 +473,7 @@ void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, Polymorphic
     X86Assembler::link(code, success, reinterpret_cast<void*>(successDest));
 
     structure->ref();
-    polymorphicStructures->list[currentIndex].set(cachedOffset, code, structure);
+    polymorphicStructures->list[currentIndex].set(code, structure);
 
     // Finally repatch the jump to slow case back in the hot path to jump here instead.
     intptr_t jmpLocation = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + repatchOffsetGetByIdBranchToSlowCase;
@@ -523,7 +514,7 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi
 
     structure->ref();
     prototypeStructure->ref();
-    prototypeStructures->list[currentIndex].set(cachedOffset, code, structure, prototypeStructure);
+    prototypeStructures->list[currentIndex].set(code, structure, prototypeStructure);
 
     // Finally repatch the jump to slow case back in the hot path to jump here instead.
     intptr_t jmpLocation = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + repatchOffsetGetByIdBranchToSlowCase;
@@ -573,7 +564,7 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
     // Track the stub we have created so that it will be deleted later.
     structure->ref();
     chain->ref();
-    prototypeStructures->list[currentIndex].set(cachedOffset, code, structure, chain);
+    prototypeStructures->list[currentIndex].set(code, structure, chain);
 
     // Finally repatch the jump to slow case back in the hot path to jump here instead.
     intptr_t jmpLocation = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + repatchOffsetGetByIdBranchToSlowCase;