Multiple CodeBlock should be able to share the same instruction
stream without copying
https://bugs.webkit.org/show_bug.cgi?id=71978
Reviewed by Oliver Hunt.
This refactors CodeBlock::m_instructions to be a Vector boxed in a
ref-counted object, but otherwise does not take advantage of this.
This is performance neutral.
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::printStructure):
(JSC::CodeBlock::printStructures):
(JSC::CodeBlock::dump):
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::visitAggregate):
(JSC::CodeBlock::shrinkToFit):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::hasInstructions):
(JSC::CodeBlock::numberOfInstructions):
(JSC::CodeBlock::instructions):
* jit/JIT.cpp:
(JSC::JIT::JIT):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@99810 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index d797d71..ad6d8c6 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,30 @@
+2011-11-09 Filip Pizlo <fpizlo@apple.com>
+
+ Multiple CodeBlock should be able to share the same instruction
+ stream without copying
+ https://bugs.webkit.org/show_bug.cgi?id=71978
+
+ Reviewed by Oliver Hunt.
+
+ This refactors CodeBlock::m_instructions to be a Vector boxed in a
+ ref-counted object, but otherwise does not take advantage of this.
+
+ This is performance neutral.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::printStructure):
+ (JSC::CodeBlock::printStructures):
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::CodeBlock):
+ (JSC::CodeBlock::visitAggregate):
+ (JSC::CodeBlock::shrinkToFit):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::hasInstructions):
+ (JSC::CodeBlock::numberOfInstructions):
+ (JSC::CodeBlock::instructions):
+ * jit/JIT.cpp:
+ (JSC::JIT::JIT):
+
2011-11-09 Gavin Barraclough <barraclough@apple.com>
Renovate ARMv7 assembler/macro-assembler
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index d560eac..82a664c 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -284,14 +284,14 @@
void CodeBlock::printStructure(const char* name, const Instruction* vPC, int operand) const
{
- unsigned instructionOffset = vPC - m_instructions.begin();
+ unsigned instructionOffset = vPC - instructions().begin();
printf(" [%4d] %s: %s\n", instructionOffset, name, pointerToSourceString(vPC[operand].u.structure).utf8().data());
}
void CodeBlock::printStructures(const Instruction* vPC) const
{
Interpreter* interpreter = m_globalData->interpreter;
- unsigned instructionOffset = vPC - m_instructions.begin();
+ unsigned instructionOffset = vPC - instructions().begin();
if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id)) {
printStructure("get_by_id", vPC, 4);
@@ -336,23 +336,23 @@
void CodeBlock::dump(ExecState* exec) const
{
- if (m_instructions.isEmpty()) {
+ if (!m_instructions) {
printf("No instructions available.\n");
return;
}
size_t instructionCount = 0;
- for (size_t i = 0; i < m_instructions.size(); i += opcodeLengths[exec->interpreter()->getOpcodeID(m_instructions[i].u.opcode)])
+ for (size_t i = 0; i < instructions().size(); i += opcodeLengths[exec->interpreter()->getOpcodeID(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)),
+ static_cast<unsigned long>(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();
+ Vector<Instruction>::const_iterator begin = instructions().begin();
+ Vector<Instruction>::const_iterator end = instructions().end();
for (Vector<Instruction>::const_iterator it = begin; it != end; ++it)
dump(exec, begin, it);
@@ -390,14 +390,14 @@
if (!m_globalResolveInfos.isEmpty()) {
size_t i = 0;
do {
- printGlobalResolveInfo(m_globalResolveInfos[i], instructionOffsetForNth(exec, m_instructions, i + 1, isGlobalResolve));
+ printGlobalResolveInfo(m_globalResolveInfos[i], instructionOffsetForNth(exec, 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));
+ printStructureStubInfo(m_structureStubInfos[i], instructionOffsetForNth(exec, instructions(), i + 1, isPropertyAccess));
++i;
} while (i < m_structureStubInfos.size());
}
@@ -409,14 +409,14 @@
if (!m_globalResolveInstructions.isEmpty()) {
size_t i = 0;
do {
- printStructures(&m_instructions[m_globalResolveInstructions[i]]);
+ printStructures(&instructions()[m_globalResolveInstructions[i]]);
++i;
} while (i < m_globalResolveInstructions.size());
}
if (!m_propertyAccessInstructions.isEmpty()) {
size_t i = 0;
do {
- printStructures(&m_instructions[m_propertyAccessInstructions[i]]);
+ printStructures(&instructions()[m_propertyAccessInstructions[i]]);
++i;
} while (i < m_propertyAccessInstructions.size());
}
@@ -1416,9 +1416,8 @@
, m_isConstructor(isConstructor)
, m_ownerExecutable(globalObject->globalData(), ownerExecutable, ownerExecutable)
, m_globalData(0)
-#ifndef NDEBUG
+ , m_instructions(adoptRef(new Instructions))
, m_instructionCount(0)
-#endif
, m_argumentsRegister(-1)
, m_needsFullScopeChain(ownerExecutable->needsActivation())
, m_usesEval(ownerExecutable->usesEval())
@@ -1554,9 +1553,9 @@
#endif
#if ENABLE(INTERPRETER)
for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i)
- visitStructures(visitor, &m_instructions[m_propertyAccessInstructions[i]]);
+ visitStructures(visitor, &instructions()[m_propertyAccessInstructions[i]]);
for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i)
- visitStructures(visitor, &m_instructions[m_globalResolveInstructions[i]]);
+ visitStructures(visitor, &instructions()[m_globalResolveInstructions[i]]);
#endif
#if ENABLE(JIT)
for (size_t size = m_globalResolveInfos.size(), i = 0; i < size; ++i) {
@@ -1722,7 +1721,7 @@
void CodeBlock::shrinkToFit()
{
- m_instructions.shrinkToFit();
+ instructions().shrinkToFit();
#if ENABLE(INTERPRETER)
m_propertyAccessInstructions.shrinkToFit();
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h
index ada8d3f..893452b 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.h
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.h
@@ -438,7 +438,10 @@
void setIsNumericCompareFunction(bool isNumericCompareFunction) { m_isNumericCompareFunction = isNumericCompareFunction; }
bool isNumericCompareFunction() { return m_isNumericCompareFunction; }
- Vector<Instruction>& instructions() { return m_instructions; }
+ bool hasInstructions() const { return !!m_instructions; }
+ unsigned numberOfInstructions() const { return !m_instructions ? 0 : m_instructions->m_instructions.size(); }
+ Vector<Instruction>& instructions() { return m_instructions->m_instructions; }
+ const Vector<Instruction>& instructions() const { return m_instructions->m_instructions; }
void discardBytecode() { m_instructions.clear(); }
#ifndef NDEBUG
@@ -1015,7 +1018,10 @@
WriteBarrier<ScriptExecutable> m_ownerExecutable;
JSGlobalData* m_globalData;
- Vector<Instruction> m_instructions;
+ struct Instructions : public RefCounted<Instructions> {
+ Vector<Instruction> m_instructions;
+ };
+ RefPtr<Instructions> m_instructions;
unsigned m_instructionCount;
int m_thisRegister;
diff --git a/Source/JavaScriptCore/jit/JIT.cpp b/Source/JavaScriptCore/jit/JIT.cpp
index 200def4..e93eaf5 100644
--- a/Source/JavaScriptCore/jit/JIT.cpp
+++ b/Source/JavaScriptCore/jit/JIT.cpp
@@ -73,7 +73,7 @@
: m_interpreter(globalData->interpreter)
, m_globalData(globalData)
, m_codeBlock(codeBlock)
- , m_labels(codeBlock ? codeBlock->instructions().size() : 0)
+ , m_labels(codeBlock ? codeBlock->numberOfInstructions() : 0)
, m_bytecodeOffset((unsigned)-1)
#if USE(JSVALUE32_64)
, m_jumpTargetIndex(0)