Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (88872 => 88873)
--- trunk/Source/_javascript_Core/ChangeLog 2011-06-14 23:35:43 UTC (rev 88872)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-06-14 23:39:25 UTC (rev 88873)
@@ -1,3 +1,42 @@
+2011-06-14 Oliver Hunt <oli...@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Constant array literals result in unnecessarily large amounts of code
+ https://bugs.webkit.org/show_bug.cgi?id=62658
+
+ Add a new version of op_new_array that simply copies values from a buffer
+ we hang off of the CodeBlock, rather than generating code to place each
+ entry into the registerfile, and then copying it from the registerfile into
+ the array. This is a slight improvement on some sunspider tests, but no
+ measurable overall change. That's okay though as our goal was to reduce
+ code size without hurting performance.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::addImmediateBuffer):
+ (JSC::CodeBlock::immediateBuffer):
+ * bytecode/Opcode.h:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::addImmediateBuffer):
+ (JSC::BytecodeGenerator::emitNewArray):
+ * bytecompiler/BytecodeGenerator.h:
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ArrayNode::emitBytecode):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ * jit/JIT.h:
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_new_array):
+ (JSC::JIT::emit_op_new_array_buffer):
+ * jit/JITOpcodes32_64.cpp:
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * jit/JITStubs.h:
+
2011-06-14 Sheriff Bot <webkit.review....@gmail.com>
Unreviewed, rolling out r88841.
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (88872 => 88873)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2011-06-14 23:35:43 UTC (rev 88872)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2011-06-14 23:39:25 UTC (rev 88873)
@@ -530,6 +530,13 @@
printf("[%4d] new_array\t %s, %s, %d\n", location, registerName(exec, dst).data(), registerName(exec, argv).data(), argc);
break;
}
+ case op_new_array_buffer: {
+ int dst = (++it)->u.operand;
+ int argv = (++it)->u.operand;
+ int argc = (++it)->u.operand;
+ printf("[%4d] new_array_buffer %s, %d, %d\n", location, registerName(exec, dst).data(), argv, argc);
+ break;
+ }
case op_new_regexp: {
int r0 = (++it)->u.operand;
int re0 = (++it)->u.operand;
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (88872 => 88873)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2011-06-14 23:35:43 UTC (rev 88872)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2011-06-14 23:39:25 UTC (rev 88873)
@@ -456,6 +456,20 @@
}
RegExp* regexp(int index) const { ASSERT(m_rareData); return m_rareData->m_regexps[index].get(); }
+ unsigned addImmediateBuffer(unsigned length)
+ {
+ createRareDataIfNecessary();
+ unsigned size = m_rareData->m_immediateBuffers.size();
+ m_rareData->m_immediateBuffers.append(Vector<JSValue>(length));
+ return size;
+ }
+
+ JSValue* immediateBuffer(unsigned index)
+ {
+ ASSERT(m_rareData);
+ return m_rareData->m_immediateBuffers[index].data();
+ }
+
JSGlobalObject* globalObject() { return m_globalObject.get(); }
// Jump Tables
@@ -559,6 +573,9 @@
// Rare Constants
Vector<WriteBarrier<RegExp> > m_regexps;
+ // Buffers used for large array literals
+ Vector<Vector<JSValue> > m_immediateBuffers;
+
// Jump Tables
Vector<SimpleJumpTable> m_immediateSwitchJumpTables;
Vector<SimpleJumpTable> m_characterSwitchJumpTables;
Modified: trunk/Source/_javascript_Core/bytecode/Opcode.h (88872 => 88873)
--- trunk/Source/_javascript_Core/bytecode/Opcode.h 2011-06-14 23:35:43 UTC (rev 88872)
+++ trunk/Source/_javascript_Core/bytecode/Opcode.h 2011-06-14 23:39:25 UTC (rev 88873)
@@ -49,6 +49,7 @@
\
macro(op_new_object, 2) \
macro(op_new_array, 4) \
+ macro(op_new_array_buffer, 4) \
macro(op_new_regexp, 3) \
macro(op_mov, 3) \
\
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (88872 => 88873)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2011-06-14 23:35:43 UTC (rev 88872)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2011-06-14 23:39:25 UTC (rev 88873)
@@ -1541,8 +1541,44 @@
return dst;
}
-RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements)
+unsigned BytecodeGenerator::addImmediateBuffer(unsigned length)
{
+ return m_codeBlock->addImmediateBuffer(length);
+}
+
+RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements, unsigned length)
+{
+#if !ASSERT_DISABLED
+ unsigned checkLength = 0;
+#endif
+ bool hadNonNumber = false;
+ if (length) {
+ for (ElementNode* n = elements; n; n = n->next()) {
+ if (!n->value()->isNumber()) {
+ hadNonNumber = true;
+ break;
+ }
+ if (n->elision())
+ break;
+#if !ASSERT_DISABLED
+ checkLength++;
+#endif
+ }
+ if (!hadNonNumber) {
+ ASSERT(length == checkLength);
+ unsigned immediateBufferIndex = addImmediateBuffer(length);
+ JSValue* immediateBuffer = m_codeBlock->immediateBuffer(immediateBufferIndex);
+ unsigned index = 0;
+ for (ElementNode* n = elements; index < length; n = n->next())
+ immediateBuffer[index++] = jsNumber(static_cast<NumberNode*>(n->value())->value());
+ emitOpcode(op_new_array_buffer);
+ instructions().append(dst->index());
+ instructions().append(immediateBufferIndex);
+ instructions().append(length);
+ return dst;
+ }
+ }
+
Vector<RefPtr<RegisterID>, 16> argv;
for (ElementNode* n = elements; n; n = n->next()) {
if (n->elision())
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (88872 => 88873)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2011-06-14 23:35:43 UTC (rev 88872)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2011-06-14 23:39:25 UTC (rev 88873)
@@ -285,7 +285,7 @@
RegisterID* emitUnaryNoDstOp(OpcodeID, RegisterID* src);
RegisterID* emitNewObject(RegisterID* dst);
- RegisterID* emitNewArray(RegisterID* dst, ElementNode*); // stops at first elision
+ RegisterID* emitNewArray(RegisterID* dst, ElementNode*, unsigned length); // stops at first elision
RegisterID* emitNewFunction(RegisterID* dst, FunctionBodyNode* body);
RegisterID* emitLazyNewFunction(RegisterID* dst, FunctionBodyNode* body);
@@ -477,6 +477,8 @@
RegisterID* addConstantValue(JSValue);
unsigned addRegExp(RegExp*);
+ unsigned addImmediateBuffer(unsigned length);
+
FunctionExecutable* makeFunction(ExecState* exec, FunctionBodyNode* body)
{
return FunctionExecutable::create(exec, body->ident(), body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine());
Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (88872 => 88873)
--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2011-06-14 23:35:43 UTC (rev 88872)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2011-06-14 23:39:25 UTC (rev 88873)
@@ -171,9 +171,9 @@
}
if (!firstPutElement && !m_elision)
- return generator.emitNewArray(generator.finalDestination(dst), m_element);
+ return generator.emitNewArray(generator.finalDestination(dst), m_element, length);
- RefPtr<RegisterID> array = generator.emitNewArray(generator.tempDestination(dst), m_element);
+ RefPtr<RegisterID> array = generator.emitNewArray(generator.tempDestination(dst), m_element, length);
for (ElementNode* n = firstPutElement; n; n = n->next()) {
RegisterID* value = generator.emitNode(n->value());
Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (88872 => 88873)
--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2011-06-14 23:35:43 UTC (rev 88872)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2011-06-14 23:39:25 UTC (rev 88873)
@@ -1554,6 +1554,22 @@
vPC += OPCODE_LENGTH(op_new_array);
NEXT_INSTRUCTION();
}
+ DEFINE_OPCODE(op_new_array_buffer) {
+ /* new_array_buffer dst(r) index(n) argCount(n)
+
+ Constructs a new Array instance using the original
+ constructor, and puts the result in register dst.
+ The array be initialized with the values from immediateBuffer[index]
+ */
+ int dst = vPC[1].u.operand;
+ int firstArg = vPC[2].u.operand;
+ int argCount = vPC[3].u.operand;
+ ArgList args(codeBlock->immediateBuffer(firstArg), argCount);
+ callFrame->uncheckedR(dst) = JSValue(constructArray(callFrame, args));
+
+ vPC += OPCODE_LENGTH(op_new_array);
+ NEXT_INSTRUCTION();
+ }
DEFINE_OPCODE(op_new_regexp) {
/* new_regexp dst(r) regExp(re)
Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (88872 => 88873)
--- trunk/Source/_javascript_Core/jit/JIT.cpp 2011-06-14 23:35:43 UTC (rev 88872)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp 2011-06-14 23:39:25 UTC (rev 88873)
@@ -272,6 +272,7 @@
DEFINE_OP(op_neq)
DEFINE_OP(op_neq_null)
DEFINE_OP(op_new_array)
+ DEFINE_OP(op_new_array_buffer)
DEFINE_OP(op_new_func)
DEFINE_OP(op_new_func_exp)
DEFINE_OP(op_new_object)
Modified: trunk/Source/_javascript_Core/jit/JIT.h (88872 => 88873)
--- trunk/Source/_javascript_Core/jit/JIT.h 2011-06-14 23:35:43 UTC (rev 88872)
+++ trunk/Source/_javascript_Core/jit/JIT.h 2011-06-14 23:39:25 UTC (rev 88873)
@@ -778,6 +778,7 @@
void emit_op_neq(Instruction*);
void emit_op_neq_null(Instruction*);
void emit_op_new_array(Instruction*);
+ void emit_op_new_array_buffer(Instruction*);
void emit_op_new_func(Instruction*);
void emit_op_new_func_exp(Instruction*);
void emit_op_new_object(Instruction*);
Modified: trunk/Source/_javascript_Core/jit/JITOpcodes.cpp (88872 => 88873)
--- trunk/Source/_javascript_Core/jit/JITOpcodes.cpp 2011-06-14 23:35:43 UTC (rev 88872)
+++ trunk/Source/_javascript_Core/jit/JITOpcodes.cpp 2011-06-14 23:39:25 UTC (rev 88873)
@@ -579,14 +579,6 @@
ret();
}
-void JIT::emit_op_new_array(Instruction* currentInstruction)
-{
- JITStubCall stubCall(this, cti_op_new_array);
- stubCall.addArgument(Imm32(currentInstruction[2].u.operand));
- stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
- stubCall.call(currentInstruction[1].u.operand);
-}
-
void JIT::emit_op_resolve(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_resolve);
@@ -1734,6 +1726,22 @@
lazyJump.link(this);
}
+void JIT::emit_op_new_array(Instruction* currentInstruction)
+{
+ JITStubCall stubCall(this, cti_op_new_array);
+ stubCall.addArgument(Imm32(currentInstruction[2].u.operand));
+ stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
+ stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_new_array_buffer(Instruction* currentInstruction)
+{
+ JITStubCall stubCall(this, cti_op_new_array_buffer);
+ stubCall.addArgument(Imm32(currentInstruction[2].u.operand));
+ stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
+ stubCall.call(currentInstruction[1].u.operand);
+}
+
} // namespace JSC
#endif // ENABLE(JIT)
Modified: trunk/Source/_javascript_Core/jit/JITOpcodes32_64.cpp (88872 => 88873)
--- trunk/Source/_javascript_Core/jit/JITOpcodes32_64.cpp 2011-06-14 23:35:43 UTC (rev 88872)
+++ trunk/Source/_javascript_Core/jit/JITOpcodes32_64.cpp 2011-06-14 23:39:25 UTC (rev 88873)
@@ -733,14 +733,6 @@
argsNotCreated.link(this);
}
-void JIT::emit_op_new_array(Instruction* currentInstruction)
-{
- JITStubCall stubCall(this, cti_op_new_array);
- stubCall.addArgument(Imm32(currentInstruction[2].u.operand));
- stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
- stubCall.call(currentInstruction[1].u.operand);
-}
-
void JIT::emit_op_resolve(Instruction* currentInstruction)
{
JITStubCall stubCall(this, cti_op_resolve);
Modified: trunk/Source/_javascript_Core/jit/JITStubs.cpp (88872 => 88873)
--- trunk/Source/_javascript_Core/jit/JITStubs.cpp 2011-06-14 23:35:43 UTC (rev 88872)
+++ trunk/Source/_javascript_Core/jit/JITStubs.cpp 2011-06-14 23:39:25 UTC (rev 88873)
@@ -2260,6 +2260,14 @@
return constructArray(stackFrame.callFrame, argList);
}
+DEFINE_STUB_FUNCTION(JSObject*, op_new_array_buffer)
+{
+ STUB_INIT_STACK_FRAME(stackFrame);
+
+ ArgList argList(stackFrame.callFrame->codeBlock()->immediateBuffer(stackFrame.args[0].int32()), stackFrame.args[1].int32());
+ return constructArray(stackFrame.callFrame, argList);
+}
+
DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve)
{
STUB_INIT_STACK_FRAME(stackFrame);
Modified: trunk/Source/_javascript_Core/jit/JITStubs.h (88872 => 88873)
--- trunk/Source/_javascript_Core/jit/JITStubs.h 2011-06-14 23:35:43 UTC (rev 88872)
+++ trunk/Source/_javascript_Core/jit/JITStubs.h 2011-06-14 23:39:25 UTC (rev 88873)
@@ -380,6 +380,7 @@
EncodedJSValue JIT_STUB cti_op_urshift(STUB_ARGS_DECLARATION);
EncodedJSValue JIT_STUB cti_to_object(STUB_ARGS_DECLARATION);
JSObject* JIT_STUB cti_op_new_array(STUB_ARGS_DECLARATION);
+ JSObject* JIT_STUB cti_op_new_array_buffer(STUB_ARGS_DECLARATION);
JSObject* JIT_STUB cti_op_new_func(STUB_ARGS_DECLARATION);
JSObject* JIT_STUB cti_op_new_func_exp(STUB_ARGS_DECLARATION);
JSObject* JIT_STUB cti_op_new_object(STUB_ARGS_DECLARATION);