Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (89953 => 89954)
--- trunk/Source/_javascript_Core/ChangeLog 2011-06-28 20:09:55 UTC (rev 89953)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-06-28 20:21:37 UTC (rev 89954)
@@ -1,3 +1,26 @@
+2011-06-28 Oliver Hunt <[email protected]>
+
+ Reviewed by Gavin Barraclough.
+
+ Make constant array optimisation less strict about what constitutes a constant
+ https://bugs.webkit.org/show_bug.cgi?id=63554
+
+ Now allow string constants in array literals to actually be considered constant,
+ and so avoid codegen in array literals with strings in them.
+
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::addConstantBuffer):
+ (JSC::CodeBlock::constantBuffer):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::addConstantBuffer):
+ (JSC::BytecodeGenerator::addStringConstant):
+ (JSC::BytecodeGenerator::emitNewArray):
+ * bytecompiler/BytecodeGenerator.h:
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+
2011-06-28 Gavin Barraclough <[email protected]>
Reviewed by Oliver Hunt.
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (89953 => 89954)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2011-06-28 20:09:55 UTC (rev 89953)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2011-06-28 20:21:37 UTC (rev 89954)
@@ -477,18 +477,18 @@
}
RegExp* regexp(int index) const { ASSERT(m_rareData); return m_rareData->m_regexps[index].get(); }
- unsigned addImmediateBuffer(unsigned length)
+ unsigned addConstantBuffer(unsigned length)
{
createRareDataIfNecessary();
- unsigned size = m_rareData->m_immediateBuffers.size();
- m_rareData->m_immediateBuffers.append(Vector<JSValue>(length));
+ unsigned size = m_rareData->m_constantBuffers.size();
+ m_rareData->m_constantBuffers.append(Vector<JSValue>(length));
return size;
}
- JSValue* immediateBuffer(unsigned index)
+ JSValue* constantBuffer(unsigned index)
{
ASSERT(m_rareData);
- return m_rareData->m_immediateBuffers[index].data();
+ return m_rareData->m_constantBuffers[index].data();
}
JSGlobalObject* globalObject() { return m_globalObject.get(); }
@@ -595,7 +595,7 @@
Vector<WriteBarrier<RegExp> > m_regexps;
// Buffers used for large array literals
- Vector<Vector<JSValue> > m_immediateBuffers;
+ Vector<Vector<JSValue> > m_constantBuffers;
// Jump Tables
Vector<SimpleJumpTable> m_immediateSwitchJumpTables;
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (89953 => 89954)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2011-06-28 20:09:55 UTC (rev 89953)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2011-06-28 20:21:37 UTC (rev 89954)
@@ -1508,21 +1508,31 @@
return dst;
}
-unsigned BytecodeGenerator::addImmediateBuffer(unsigned length)
+unsigned BytecodeGenerator::addConstantBuffer(unsigned length)
{
- return m_codeBlock->addImmediateBuffer(length);
+ return m_codeBlock->addConstantBuffer(length);
}
+JSString* BytecodeGenerator::addStringConstant(const Identifier& identifier)
+{
+ JSString*& stringInMap = m_stringMap.add(identifier.impl(), 0).first->second;
+ if (!stringInMap) {
+ stringInMap = jsString(globalData(), identifier.ustring());
+ addConstantValue(stringInMap);
+ }
+ return stringInMap;
+}
+
RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements, unsigned length)
{
#if !ASSERT_DISABLED
unsigned checkLength = 0;
#endif
- bool hadNonNumber = false;
+ bool hadVariableExpression = false;
if (length) {
for (ElementNode* n = elements; n; n = n->next()) {
- if (!n->value()->isNumber()) {
- hadNonNumber = true;
+ if (!n->value()->isNumber() && !n->value()->isString()) {
+ hadVariableExpression = true;
break;
}
if (n->elision())
@@ -1531,16 +1541,22 @@
checkLength++;
#endif
}
- if (!hadNonNumber) {
+ if (!hadVariableExpression) {
ASSERT(length == checkLength);
- unsigned immediateBufferIndex = addImmediateBuffer(length);
- JSValue* immediateBuffer = m_codeBlock->immediateBuffer(immediateBufferIndex);
+ unsigned constantBufferIndex = addConstantBuffer(length);
+ JSValue* constantBuffer = m_codeBlock->constantBuffer(constantBufferIndex);
unsigned index = 0;
- for (ElementNode* n = elements; index < length; n = n->next())
- immediateBuffer[index++] = jsNumber(static_cast<NumberNode*>(n->value())->value());
+ for (ElementNode* n = elements; index < length; n = n->next()) {
+ if (n->value()->isNumber())
+ constantBuffer[index++] = jsNumber(static_cast<NumberNode*>(n->value())->value());
+ else {
+ ASSERT(n->value()->isString());
+ constantBuffer[index++] = addStringConstant(static_cast<StringNode*>(n->value())->value());
+ }
+ }
emitOpcode(op_new_array_buffer);
instructions().append(dst->index());
- instructions().append(immediateBufferIndex);
+ instructions().append(constantBufferIndex);
instructions().append(length);
return dst;
}
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (89953 => 89954)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2011-06-28 20:09:55 UTC (rev 89953)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h 2011-06-28 20:21:37 UTC (rev 89954)
@@ -469,7 +469,7 @@
RegisterID* addConstantValue(JSValue);
unsigned addRegExp(RegExp*);
- unsigned addImmediateBuffer(unsigned length);
+ unsigned addConstantBuffer(unsigned length);
FunctionExecutable* makeFunction(ExecState* exec, FunctionBodyNode* body)
{
@@ -481,6 +481,8 @@
return FunctionExecutable::create(globalData, body->ident(), body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine());
}
+ JSString* addStringConstant(const Identifier&);
+
void addLineInfo(unsigned lineNo)
{
#if !ENABLE(OPCODE_SAMPLING)
Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (89953 => 89954)
--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2011-06-28 20:09:55 UTC (rev 89953)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2011-06-28 20:21:37 UTC (rev 89954)
@@ -1606,12 +1606,12 @@
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]
+ The array be initialized with the values from constantBuffer[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);
+ ArgList args(codeBlock->constantBufferfirstArg), argCount);
callFrame->uncheckedR(dst) = JSValue(constructArray(callFrame, args));
vPC += OPCODE_LENGTH(op_new_array);
Modified: trunk/Source/_javascript_Core/jit/JITStubs.cpp (89953 => 89954)
--- trunk/Source/_javascript_Core/jit/JITStubs.cpp 2011-06-28 20:09:55 UTC (rev 89953)
+++ trunk/Source/_javascript_Core/jit/JITStubs.cpp 2011-06-28 20:21:37 UTC (rev 89954)
@@ -2264,7 +2264,7 @@
{
STUB_INIT_STACK_FRAME(stackFrame);
- ArgList argList(stackFrame.callFrame->codeBlock()->immediateBuffer(stackFrame.args[0].int32()), stackFrame.args[1].int32());
+ ArgList argList(stackFrame.callFrame->codeBlock()->constantBuffer(stackFrame.args[0].int32()), stackFrame.args[1].int32());
return constructArray(stackFrame.callFrame, argList);
}