Stop making unnecessary copy of CodeBlock Identifier Vector
https://bugs.webkit.org/show_bug.cgi?id=119702

Reviewed by Michael Saboff.

Make CodeBlock simply use a separate Vector for additional Identifiers
and use the UnlinkedCodeBlock for the initial set of identifiers.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::printGetByIdOp):
(JSC::dumpStructure):
(JSC::dumpChain):
(JSC::CodeBlock::printGetByIdCacheStatus):
(JSC::CodeBlock::printPutByIdOp):
(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::shrinkToFit):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::numberOfIdentifiers):
(JSC::CodeBlock::numberOfAdditionalIdentifiers):
(JSC::CodeBlock::addAdditionalIdentifier):
(JSC::CodeBlock::identifier):
* dfg/DFGDesiredIdentifiers.cpp:
(JSC::DFG::DesiredIdentifiers::reallyAdd):
* jit/JIT.h:
* jit/JITOpcodes.cpp:
(JSC::JIT::emitSlow_op_get_arguments_length):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_get_by_id):
(JSC::JIT::compileGetByIdHotPath):
(JSC::JIT::emitSlow_op_get_by_id):
(JSC::JIT::compileGetByIdSlowCase):
(JSC::JIT::emitSlow_op_put_by_id):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emit_op_get_by_id):
(JSC::JIT::compileGetByIdHotPath):
(JSC::JIT::compileGetByIdSlowCase):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153962 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index 2d7f27b..4e7022a 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -283,12 +283,12 @@
     int r0 = (++it)->u.operand;
     int r1 = (++it)->u.operand;
     int id0 = (++it)->u.operand;
-    out.printf("[%4d] %s\t %s, %s, %s", location, op, registerName(r0).data(), registerName(r1).data(), idName(id0, m_identifiers[id0]).data());
+    out.printf("[%4d] %s\t %s, %s, %s", location, op, registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data());
     it += 4; // Increment up to the value profiler.
 }
 
 #if ENABLE(JIT) || ENABLE(LLINT) // unused in some configurations
-static void dumpStructure(PrintStream& out, const char* name, ExecState* exec, Structure* structure, Identifier& ident)
+static void dumpStructure(PrintStream& out, const char* name, ExecState* exec, Structure* structure, const Identifier& ident)
 {
     if (!structure)
         return;
@@ -302,7 +302,7 @@
 #endif
 
 #if ENABLE(JIT) // unused when not ENABLE(JIT), leading to silly warnings
-static void dumpChain(PrintStream& out, ExecState* exec, StructureChain* chain, Identifier& ident)
+static void dumpChain(PrintStream& out, ExecState* exec, StructureChain* chain, const Identifier& ident)
 {
     out.printf("chain = %p: [", chain);
     bool first = true;
@@ -323,7 +323,7 @@
 {
     Instruction* instruction = instructions().begin() + location;
 
-    Identifier& ident = identifier(instruction[3].u.operand);
+    const Identifier& ident = identifier(instruction[3].u.operand);
     
     UNUSED_PARAM(ident); // tell the compiler to shut up in certain platform configurations.
     
@@ -470,7 +470,7 @@
     int r0 = (++it)->u.operand;
     int id0 = (++it)->u.operand;
     int r1 = (++it)->u.operand;
-    out.printf("[%4d] %s\t %s, %s, %s", location, op, registerName(r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(r1).data());
+    out.printf("[%4d] %s\t %s, %s, %s", location, op, registerName(r0).data(), idName(id0, identifier(id0)).data(), registerName(r1).data());
     it += 5;
 }
 
@@ -510,13 +510,13 @@
     for (const Instruction* it = begin; it != end; ++it)
         dumpBytecode(out, exec, begin, it);
 
-    if (!m_identifiers.isEmpty()) {
+    if (numberOfIdentifiers()) {
         out.printf("\nIdentifiers:\n");
         size_t i = 0;
         do {
-            out.printf("  id%u = %s\n", static_cast<unsigned>(i), m_identifiers[i].string().utf8().data());
+            out.printf("  id%u = %s\n", static_cast<unsigned>(i), identifier(i).string().utf8().data());
             ++i;
-        } while (i != m_identifiers.size());
+        } while (i != numberOfIdentifiers());
     }
 
     if (!m_constantRegisters.isEmpty()) {
@@ -972,14 +972,14 @@
             int id0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int r2 = (++it)->u.operand;
-            out.printf("[%4d] put_getter_setter\t %s, %s, %s, %s", location, registerName(r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(r1).data(), registerName(r2).data());
+            out.printf("[%4d] put_getter_setter\t %s, %s, %s, %s", location, registerName(r0).data(), idName(id0, identifier(id0)).data(), registerName(r1).data(), registerName(r2).data());
             break;
         }
         case op_del_by_id: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int id0 = (++it)->u.operand;
-            out.printf("[%4d] del_by_id\t %s, %s, %s", location, registerName(r0).data(), registerName(r1).data(), idName(id0, m_identifiers[id0]).data());
+            out.printf("[%4d] del_by_id\t %s, %s, %s", location, registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data());
             break;
         }
         case op_get_by_val: {
@@ -1246,7 +1246,7 @@
             int id0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             unsigned attributes = (++it)->u.operand;
-            out.printf("[%4d] push_name_scope \t%s, %s, %u", location, idName(id0, m_identifiers[id0]).data(), registerName(r1).data(), attributes);
+            out.printf("[%4d] push_name_scope \t%s, %s, %u", location, idName(id0, identifier(id0)).data(), registerName(r1).data(), attributes);
             break;
         }
         case op_catch: {
@@ -1293,7 +1293,7 @@
             int id0 = (++it)->u.operand;
             ++it; // ResolveType
             ++it; // depth
-            out.printf("[%4d] resolve_scope\t %s, %s", location, registerName(r0).data(), idName(id0, m_identifiers[id0]).data());
+            out.printf("[%4d] resolve_scope\t %s, %s", location, registerName(r0).data(), idName(id0, identifier(id0)).data());
             break;
         }
         case op_get_from_scope: {
@@ -1304,7 +1304,7 @@
             ++it; // Structure
             ++it; // Operand
             ++it; // Skip value profile.
-            out.printf("[%4d] get_from_scope\t %s, %s, %s, %d", location, registerName(r0).data(), registerName(r1).data(), idName(id0, m_identifiers[id0]).data(), resolveModeAndType);
+            out.printf("[%4d] get_from_scope\t %s, %s, %s, %d", location, registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data(), resolveModeAndType);
             break;
         }
         case op_put_to_scope: {
@@ -1314,7 +1314,7 @@
             int resolveModeAndType = (++it)->u.operand;
             ++it; // Structure
             ++it; // Operand
-            out.printf("[%4d] put_to_scope\t %s, %s, %s, %d", location, registerName(r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(r1).data(), resolveModeAndType);
+            out.printf("[%4d] put_to_scope\t %s, %s, %s, %d", location, registerName(r0).data(), idName(id0, identifier(id0)).data(), registerName(r1).data(), resolveModeAndType);
             break;
         }
 #if ENABLE(LLINT_C_LOOP)
@@ -1491,7 +1491,7 @@
     , m_sourceOffset(other.m_sourceOffset)
     , m_firstLineColumnOffset(other.m_firstLineColumnOffset)
     , m_codeType(other.m_codeType)
-    , m_identifiers(other.m_identifiers)
+    , m_additionalIdentifiers(other.m_additionalIdentifiers)
     , m_constantRegisters(other.m_constantRegisters)
     , m_functionDecls(other.m_functionDecls)
     , m_functionExprs(other.m_functionExprs)
@@ -1551,7 +1551,7 @@
 #if DUMP_CODE_BLOCK_STATISTICS
     liveCodeBlockSet.add(this);
 #endif
-    setIdentifiers(unlinkedCodeBlock->identifiers());
+
     setConstantRegisters(unlinkedCodeBlock->constantRegisters());
     if (unlinkedCodeBlock->usesGlobalObject())
         m_constantRegisters[unlinkedCodeBlock->globalObjectRegister()].set(*m_vm, ownerExecutable, m_globalObject.get());
@@ -1764,7 +1764,7 @@
         }
 
         case op_resolve_scope: {
-            Identifier& ident = identifier(pc[i + 2].u.operand);
+            const Identifier& ident = identifier(pc[i + 2].u.operand);
             ResolveType type = static_cast<ResolveType>(pc[i + 3].u.operand);
 
             ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), scope, ident, Get, type);
@@ -1782,7 +1782,7 @@
 #endif
 
             // get_from_scope dst, scope, id, ResolveModeAndType, Structure, Operand
-            Identifier& ident = identifier(pc[i + 3].u.operand);
+            const Identifier& ident = identifier(pc[i + 3].u.operand);
             ResolveModeAndType modeAndType = ResolveModeAndType(pc[i + 4].u.operand);
             ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), scope, ident, Get, modeAndType.type());
 
@@ -1795,7 +1795,7 @@
 
         case op_put_to_scope: {
             // put_to_scope scope, id, value, ResolveModeAndType, Structure, Operand
-            Identifier& ident = identifier(pc[i + 2].u.operand);
+            const Identifier& ident = identifier(pc[i + 2].u.operand);
             ResolveModeAndType modeAndType = ResolveModeAndType(pc[i + 4].u.operand);
             ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), scope, ident, Put, modeAndType.type());
 
@@ -2454,7 +2454,7 @@
 #endif
     
     if (shrinkMode == EarlyShrink) {
-        m_identifiers.shrinkToFit();
+        m_additionalIdentifiers.shrinkToFit();
         m_functionDecls.shrinkToFit();
         m_functionExprs.shrinkToFit();
         m_constantRegisters.shrinkToFit();