Changeset 88841 in webkit


Ignore:
Timestamp:
Jun 14, 2011 12:10:20 PM (13 years ago)
Author:
oliver@apple.com
Message:

2011-06-14 Oliver Hunt <oliver@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:
Location:
trunk/Source/JavaScriptCore
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r88833 r88841  
     12011-06-14  Oliver Hunt  <oliver@apple.com>
     2
     3        Reviewed by Gavin Barraclough.
     4
     5        Constant array literals result in unnecessarily large amounts of code
     6        https://bugs.webkit.org/show_bug.cgi?id=62658
     7
     8        Add a new version of op_new_array that simply copies values from a buffer
     9        we hang off of the CodeBlock, rather than generating code to place each
     10        entry into the registerfile, and then copying it from the registerfile into
     11        the array.  This is a slight improvement on some sunspider tests, but no
     12        measurable overall change.  That's okay though as our goal was to reduce
     13        code size without hurting performance.
     14
     15        * bytecode/CodeBlock.cpp:
     16        (JSC::CodeBlock::dump):
     17        * bytecode/CodeBlock.h:
     18        (JSC::CodeBlock::addImmediateBuffer):
     19        (JSC::CodeBlock::immediateBuffer):
     20        * bytecode/Opcode.h:
     21        * bytecompiler/BytecodeGenerator.cpp:
     22        (JSC::BytecodeGenerator::addImmediateBuffer):
     23        (JSC::BytecodeGenerator::emitNewArray):
     24        * bytecompiler/BytecodeGenerator.h:
     25        * bytecompiler/NodesCodegen.cpp:
     26        (JSC::ArrayNode::emitBytecode):
     27        * interpreter/Interpreter.cpp:
     28        (JSC::Interpreter::privateExecute):
     29        * jit/JIT.cpp:
     30        (JSC::JIT::privateCompileMainPass):
     31        * jit/JIT.h:
     32        * jit/JITOpcodes.cpp:
     33        (JSC::JIT::emit_op_new_array):
     34        (JSC::JIT::emit_op_new_array_buffer):
     35        * jit/JITOpcodes32_64.cpp:
     36        * jit/JITStubs.cpp:
     37        (JSC::DEFINE_STUB_FUNCTION):
     38        * jit/JITStubs.h:
     39
    1402011-06-14  Stephanie Lewis  <slewis@apple.com>
    241
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r88821 r88841  
    531531            break;
    532532        }
     533        case op_new_array_buffer: {
     534            int dst = (++it)->u.operand;
     535            int argv = (++it)->u.operand;
     536            int argc = (++it)->u.operand;
     537            printf("[%4d] new_array_buffer %s, %d, %d\n", location, registerName(exec, dst).data(), argv, argc);
     538            break;
     539        }
    533540        case op_new_regexp: {
    534541            int r0 = (++it)->u.operand;
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.h

    r87359 r88841  
    457457        RegExp* regexp(int index) const { ASSERT(m_rareData); return m_rareData->m_regexps[index].get(); }
    458458
     459        unsigned addImmediateBuffer(unsigned length)
     460        {
     461            createRareDataIfNecessary();
     462            unsigned size = m_rareData->m_immediateBuffers.size();
     463            m_rareData->m_immediateBuffers.append(Vector<JSValue>(length));
     464            return size;
     465        }
     466
     467        JSValue* immediateBuffer(unsigned index)
     468        {
     469            ASSERT(m_rareData);
     470            return m_rareData->m_immediateBuffers[index].data();
     471        }
     472
    459473        JSGlobalObject* globalObject() { return m_globalObject.get(); }
    460474
     
    560574            Vector<WriteBarrier<RegExp> > m_regexps;
    561575
     576            // Buffers used for large array literals
     577            Vector<Vector<JSValue> > m_immediateBuffers;
     578           
    562579            // Jump Tables
    563580            Vector<SimpleJumpTable> m_immediateSwitchJumpTables;
  • trunk/Source/JavaScriptCore/bytecode/Opcode.h

    r81380 r88841  
    5050        macro(op_new_object, 2) \
    5151        macro(op_new_array, 4) \
     52        macro(op_new_array_buffer, 4) \
    5253        macro(op_new_regexp, 3) \
    5354        macro(op_mov, 3) \
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r87359 r88841  
    15421542}
    15431543
    1544 RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements)
    1545 {
     1544unsigned BytecodeGenerator::addImmediateBuffer(unsigned length)
     1545{
     1546    return m_codeBlock->addImmediateBuffer(length);
     1547}
     1548
     1549RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements, unsigned length)
     1550{
     1551#if !ASSERT_DISABLED
     1552    unsigned checkLength = 0;
     1553#endif
     1554    bool hadNonNumber = false;
     1555    for (ElementNode* n = elements; n; n = n->next()) {
     1556#if !ASSERT_DISABLED
     1557        checkLength++;
     1558#endif
     1559        if (!n->value()->isNumber()) {
     1560            hadNonNumber = true;
     1561            break;
     1562        }
     1563    }
     1564    if (!hadNonNumber) {
     1565        ASSERT(length == checkLength);
     1566        unsigned immediateBufferIndex = addImmediateBuffer(length);
     1567        JSValue* immediateBuffer = m_codeBlock->immediateBuffer(immediateBufferIndex);
     1568        unsigned index = 0;
     1569        for (ElementNode* n = elements; n; n = n->next())
     1570            immediateBuffer[index++] = jsNumber(static_cast<NumberNode*>(n->value())->value());
     1571        emitOpcode(op_new_array_buffer);
     1572        instructions().append(dst->index());
     1573        instructions().append(immediateBufferIndex);
     1574        instructions().append(length);
     1575        return dst;
     1576    }
     1577
    15461578    Vector<RefPtr<RegisterID>, 16> argv;
    15471579    for (ElementNode* n = elements; n; n = n->next()) {
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h

    r87346 r88841  
    286286
    287287        RegisterID* emitNewObject(RegisterID* dst);
    288         RegisterID* emitNewArray(RegisterID* dst, ElementNode*); // stops at first elision
     288        RegisterID* emitNewArray(RegisterID* dst, ElementNode*, unsigned length); // stops at first elision
    289289
    290290        RegisterID* emitNewFunction(RegisterID* dst, FunctionBodyNode* body);
     
    478478        unsigned addRegExp(RegExp*);
    479479
     480        unsigned addImmediateBuffer(unsigned length);
     481       
    480482        FunctionExecutable* makeFunction(ExecState* exec, FunctionBodyNode* body)
    481483        {
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r87445 r88841  
    172172
    173173    if (!firstPutElement && !m_elision)
    174         return generator.emitNewArray(generator.finalDestination(dst), m_element);
    175 
    176     RefPtr<RegisterID> array = generator.emitNewArray(generator.tempDestination(dst), m_element);
     174        return generator.emitNewArray(generator.finalDestination(dst), m_element, length);
     175
     176    RefPtr<RegisterID> array = generator.emitNewArray(generator.tempDestination(dst), m_element, length);
    177177
    178178    for (ElementNode* n = firstPutElement; n; n = n->next()) {
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r87586 r88841  
    15521552        callFrame->uncheckedR(dst) = JSValue(constructArray(callFrame, args));
    15531553
     1554        vPC += OPCODE_LENGTH(op_new_array);
     1555        NEXT_INSTRUCTION();
     1556    }
     1557    DEFINE_OPCODE(op_new_array_buffer) {
     1558        /* new_array_buffer dst(r) index(n) argCount(n)
     1559         
     1560         Constructs a new Array instance using the original
     1561         constructor, and puts the result in register dst.
     1562         The array be initialized with the values from immediateBuffer[index]
     1563         */
     1564        int dst = vPC[1].u.operand;
     1565        int firstArg = vPC[2].u.operand;
     1566        int argCount = vPC[3].u.operand;
     1567        ArgList args(codeBlock->immediateBuffer(firstArg), argCount);
     1568        callFrame->uncheckedR(dst) = JSValue(constructArray(callFrame, args));
     1569       
    15541570        vPC += OPCODE_LENGTH(op_new_array);
    15551571        NEXT_INSTRUCTION();
  • trunk/Source/JavaScriptCore/jit/JIT.cpp

    r88604 r88841  
    273273        DEFINE_OP(op_neq_null)
    274274        DEFINE_OP(op_new_array)
     275        DEFINE_OP(op_new_array_buffer)
    275276        DEFINE_OP(op_new_func)
    276277        DEFINE_OP(op_new_func_exp)
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r88604 r88841  
    779779        void emit_op_neq_null(Instruction*);
    780780        void emit_op_new_array(Instruction*);
     781        void emit_op_new_array_buffer(Instruction*);
    781782        void emit_op_new_func(Instruction*);
    782783        void emit_op_new_func_exp(Instruction*);
  • trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp

    r88604 r88841  
    580580}
    581581
    582 void JIT::emit_op_new_array(Instruction* currentInstruction)
    583 {
    584     JITStubCall stubCall(this, cti_op_new_array);
    585     stubCall.addArgument(Imm32(currentInstruction[2].u.operand));
    586     stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
    587     stubCall.call(currentInstruction[1].u.operand);
    588 }
    589 
    590582void JIT::emit_op_resolve(Instruction* currentInstruction)
    591583{
     
    17351727}
    17361728
     1729void JIT::emit_op_new_array(Instruction* currentInstruction)
     1730{
     1731    JITStubCall stubCall(this, cti_op_new_array);
     1732    stubCall.addArgument(Imm32(currentInstruction[2].u.operand));
     1733    stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
     1734    stubCall.call(currentInstruction[1].u.operand);
     1735}
     1736
     1737void JIT::emit_op_new_array_buffer(Instruction* currentInstruction)
     1738{
     1739    JITStubCall stubCall(this, cti_op_new_array_buffer);
     1740    stubCall.addArgument(Imm32(currentInstruction[2].u.operand));
     1741    stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
     1742    stubCall.call(currentInstruction[1].u.operand);
     1743}
     1744
    17371745} // namespace JSC
    17381746
  • trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp

    r88604 r88841  
    734734}
    735735
    736 void JIT::emit_op_new_array(Instruction* currentInstruction)
    737 {
    738     JITStubCall stubCall(this, cti_op_new_array);
    739     stubCall.addArgument(Imm32(currentInstruction[2].u.operand));
    740     stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
    741     stubCall.call(currentInstruction[1].u.operand);
    742 }
    743 
    744736void JIT::emit_op_resolve(Instruction* currentInstruction)
    745737{
  • trunk/Source/JavaScriptCore/jit/JITStubs.cpp

    r88604 r88841  
    22582258
    22592259    ArgList argList(&stackFrame.callFrame->registers()[stackFrame.args[0].int32()], stackFrame.args[1].int32());
     2260    return constructArray(stackFrame.callFrame, argList);
     2261}
     2262
     2263DEFINE_STUB_FUNCTION(JSObject*, op_new_array_buffer)
     2264{
     2265    STUB_INIT_STACK_FRAME(stackFrame);
     2266   
     2267    ArgList argList(stackFrame.callFrame->codeBlock()->immediateBuffer(stackFrame.args[0].int32()), stackFrame.args[1].int32());
    22602268    return constructArray(stackFrame.callFrame, argList);
    22612269}
  • trunk/Source/JavaScriptCore/jit/JITStubs.h

    r87345 r88841  
    381381    EncodedJSValue JIT_STUB cti_to_object(STUB_ARGS_DECLARATION);
    382382    JSObject* JIT_STUB cti_op_new_array(STUB_ARGS_DECLARATION);
     383    JSObject* JIT_STUB cti_op_new_array_buffer(STUB_ARGS_DECLARATION);
    383384    JSObject* JIT_STUB cti_op_new_func(STUB_ARGS_DECLARATION);
    384385    JSObject* JIT_STUB cti_op_new_func_exp(STUB_ARGS_DECLARATION);
Note: See TracChangeset for help on using the changeset viewer.