Changeset 57955 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Apr 20, 2010, 11:41:20 PM (15 years ago)
Author:
[email protected]
Message:

2010-04-20 Oliver Hunt <[email protected]>

Reviewed by Maciej Stachowiak.

[ES5] RegExp literals are constants that should be persistent across multiple function calls.
https://bugs.webkit.org/show_bug.cgi?id=37908

Dump the separate RegExp constant pool, and just use the standard JS constant pool
in codeblock. This allows us to drop op_new_regexp and all associated code as well.

  • bytecode/CodeBlock.cpp: (JSC::CodeBlock::dump): (JSC::CodeBlock::shrinkToFit):
  • bytecode/CodeBlock.h:
  • bytecode/Opcode.h:
  • bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::emitLoad):
  • bytecompiler/BytecodeGenerator.h:
  • bytecompiler/NodesCodegen.cpp: (JSC::RegExpNode::emitBytecode):
  • interpreter/Interpreter.cpp: (JSC::Interpreter::privateExecute):
  • jit/JIT.cpp: (JSC::JIT::privateCompileMainPass):
  • jit/JIT.h:
  • jit/JITOpcodes.cpp:
  • jit/JITStubs.cpp:
  • jit/JITStubs.h: (JSC::):

2010-04-20 Oliver Hunt <[email protected]>

Reviewed by Maciej Stachowiak.

[ES5] RegExp literals are constants that should be persistent across multiple function calls.
https://bugs.webkit.org/show_bug.cgi?id=37908

Add tests to ensure correct persistence of RegExp literals, and correctly avoid
sharing "identical" regexps used in different places.

  • fast/js/regexp-literals-are-constants-expected.txt: Added.
  • fast/js/regexp-literals-are-constants.html: Added.
  • fast/js/script-tests/regexp-literals-are-constants.js: Added. (test1): (returnRegExpLiteral): (returnConditionalRegExpLiteral):
Location:
trunk/JavaScriptCore
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r57946 r57955  
    44
    55        * GNUmakefile.am:
     6
     72010-04-20  Oliver Hunt  <[email protected]>
     8
     9        Reviewed by Maciej Stachowiak.
     10
     11        [ES5] RegExp literals are constants that should be persistent across multiple function calls.
     12        https://bugs.webkit.org/show_bug.cgi?id=37908
     13
     14        Dump the separate RegExp constant pool, and just use the standard JS constant pool
     15        in codeblock.  This allows us to drop op_new_regexp and all associated code as well.
     16
     17        * bytecode/CodeBlock.cpp:
     18        (JSC::CodeBlock::dump):
     19        (JSC::CodeBlock::shrinkToFit):
     20        * bytecode/CodeBlock.h:
     21        * bytecode/Opcode.h:
     22        * bytecompiler/BytecodeGenerator.cpp:
     23        (JSC::BytecodeGenerator::emitLoad):
     24        * bytecompiler/BytecodeGenerator.h:
     25        * bytecompiler/NodesCodegen.cpp:
     26        (JSC::RegExpNode::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        * jit/JITStubs.cpp:
     34        * jit/JITStubs.h:
     35        (JSC::):
    636
    7372010-04-20  Oliver Hunt  <[email protected]>
  • trunk/JavaScriptCore/bytecode/CodeBlock.cpp

    r57054 r57955  
    9090}
    9191
    92 static UString regexpToSourceString(RegExp* regExp)
    93 {
    94     char postfix[5] = { '/', 0, 0, 0, 0 };
    95     int index = 1;
    96     if (regExp->global())
    97         postfix[index++] = 'g';
    98     if (regExp->ignoreCase())
    99         postfix[index++] = 'i';
    100     if (regExp->multiline())
    101         postfix[index] = 'm';
    102 
    103     return makeString("/", regExp->pattern(), postfix);
    104 }
    105 
    106 static CString regexpName(int re, RegExp* regexp)
    107 {
    108     return makeString(regexpToSourceString(regexp), "(@re", UString::from(re), ")").UTF8String();
    109 }
    110 
    11192static UString pointerToSourceString(void* p)
    11293{
     
    365346    }
    366347
    367     if (m_rareData && !m_rareData->m_regexps.isEmpty()) {
    368         printf("\nm_regexps:\n");
    369         size_t i = 0;
    370         do {
    371             printf("  re%u = %s\n", static_cast<unsigned>(i), regexpToSourceString(m_rareData->m_regexps[i].get()).ascii());
    372             ++i;
    373         } while (i < m_rareData->m_regexps.size());
    374     }
    375 
    376348#if ENABLE(JIT)
    377349    if (!m_globalResolveInfos.isEmpty() || !m_structureStubInfos.isEmpty())
     
    509481            int argc = (++it)->u.operand;
    510482            printf("[%4d] new_array\t %s, %s, %d\n", location, registerName(exec, dst).data(), registerName(exec, argv).data(), argc);
    511             break;
    512         }
    513         case op_new_regexp: {
    514             int r0 = (++it)->u.operand;
    515             int re0 = (++it)->u.operand;
    516             printf("[%4d] new_regexp\t %s, %s\n", location, registerName(exec, r0).data(), regexpName(re0, regexp(re0)).data());
    517483            break;
    518484        }
     
    17081674    if (m_rareData) {
    17091675        m_rareData->m_exceptionHandlers.shrinkToFit();
    1710         m_rareData->m_regexps.shrinkToFit();
    17111676        m_rareData->m_immediateSwitchJumpTables.shrinkToFit();
    17121677        m_rareData->m_characterSwitchJumpTables.shrinkToFit();
  • trunk/JavaScriptCore/bytecode/CodeBlock.h

    r57054 r57955  
    459459        FunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); }
    460460
    461         unsigned addRegExp(RegExp* r) { createRareDataIfNecessary(); unsigned size = m_rareData->m_regexps.size(); m_rareData->m_regexps.append(r); return size; }
    462         RegExp* regexp(int index) const { ASSERT(m_rareData); return m_rareData->m_regexps[index].get(); }
    463 
    464 
    465461        // Jump Tables
    466462
     
    557553            Vector<HandlerInfo> m_exceptionHandlers;
    558554
    559             // Rare Constants
    560             Vector<RefPtr<RegExp> > m_regexps;
    561 
    562555            // Jump Tables
    563556            Vector<SimpleJumpTable> m_immediateSwitchJumpTables;
  • trunk/JavaScriptCore/bytecode/Opcode.h

    r55564 r57955  
    4747        macro(op_new_object, 2) \
    4848        macro(op_new_array, 4) \
    49         macro(op_new_regexp, 3) \
    5049        macro(op_mov, 3) \
    5150        \
  • trunk/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r55833 r57955  
    3535#include "JSFunction.h"
    3636#include "Interpreter.h"
     37#include "RegExp.h"
     38#include "RegExpObject.h"
    3739#include "UString.h"
    3840
     
    826828
    827829    return &m_constantPoolRegisters[index];
    828 }
    829 
    830 unsigned BytecodeGenerator::addRegExp(RegExp* r)
    831 {
    832     return m_codeBlock->addRegExp(r);
    833830}
    834831
     
    983980}
    984981
     982RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, RegExp* regExp)
     983{
     984    JSValue jsRegExp = new (globalData()) RegExpObject(m_scopeChain->globalObject()->regExpStructure(), regExp);
     985    return emitLoad(dst, jsRegExp);
     986}
     987
    985988RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValue v)
    986989{
     
    13621365}
    13631366
    1364 RegisterID* BytecodeGenerator::emitNewRegExp(RegisterID* dst, RegExp* regExp)
    1365 {
    1366     emitOpcode(op_new_regexp);
    1367     instructions().append(dst->index());
    1368     instructions().append(addRegExp(regExp));
    1369     return dst;
    1370 }
    1371 
    1372 
    13731367RegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* r0, FuncExprNode* n)
    13741368{
  • trunk/JavaScriptCore/bytecompiler/BytecodeGenerator.h

    r51735 r57955  
    265265        RegisterID* emitLoad(RegisterID* dst, double);
    266266        RegisterID* emitLoad(RegisterID* dst, const Identifier&);
     267        RegisterID* emitLoad(RegisterID* dst, RegExp* regExp);
    267268        RegisterID* emitLoad(RegisterID* dst, JSValue);
    268269
     
    277278        RegisterID* emitNewFunction(RegisterID* dst, FunctionBodyNode* body);
    278279        RegisterID* emitNewFunctionExpression(RegisterID* dst, FuncExprNode* func);
    279         RegisterID* emitNewRegExp(RegisterID* dst, RegExp* regExp);
    280280
    281281        RegisterID* emitMove(RegisterID* dst, RegisterID* src);
     
    447447        unsigned addConstant(const Identifier&);
    448448        RegisterID* addConstantValue(JSValue);
    449         unsigned addRegExp(RegExp*);
    450449
    451450        PassRefPtr<FunctionExecutable> makeFunction(ExecState* exec, FunctionBodyNode* body)
  • trunk/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r55833 r57955  
    150150    if (dst == generator.ignoredResult())
    151151        return 0;
    152     return generator.emitNewRegExp(generator.finalDestination(dst), regExp.get());
     152    return generator.emitLoad(generator.finalDestination(dst), regExp.get());
    153153}
    154154
  • trunk/JavaScriptCore/interpreter/Interpreter.cpp

    r57192 r57955  
    12361236
    12371237        vPC += OPCODE_LENGTH(op_new_array);
    1238         NEXT_INSTRUCTION();
    1239     }
    1240     DEFINE_OPCODE(op_new_regexp) {
    1241         /* new_regexp dst(r) regExp(re)
    1242 
    1243            Constructs a new RegExp instance using the original
    1244            constructor from regexp regExp, and puts the result in
    1245            register dst.
    1246         */
    1247         int dst = vPC[1].u.operand;
    1248         int regExp = vPC[2].u.operand;
    1249         callFrame->r(dst) = JSValue(new (globalData) RegExpObject(callFrame->scopeChain()->globalObject->regExpStructure(), callFrame->codeBlock()->regexp(regExp)));
    1250 
    1251         vPC += OPCODE_LENGTH(op_new_regexp);
    12521238        NEXT_INSTRUCTION();
    12531239    }
  • trunk/JavaScriptCore/jit/JIT.cpp

    r55564 r57955  
    276276        DEFINE_OP(op_new_func_exp)
    277277        DEFINE_OP(op_new_object)
    278         DEFINE_OP(op_new_regexp)
    279278        DEFINE_OP(op_next_pname)
    280279        DEFINE_OP(op_not)
  • trunk/JavaScriptCore/jit/JIT.h

    r56759 r57955  
    822822        void emit_op_new_func_exp(Instruction*);
    823823        void emit_op_new_object(Instruction*);
    824         void emit_op_new_regexp(Instruction*);
    825824        void emit_op_get_pnames(Instruction*);
    826825        void emit_op_next_pname(Instruction*);
  • trunk/JavaScriptCore/jit/JITOpcodes.cpp

    r56759 r57955  
    11711171    JITStubCall stubCall(this, cti_op_new_func_exp);
    11721172    stubCall.addArgument(ImmPtr(m_codeBlock->functionExpr(currentInstruction[2].u.operand)));
    1173     stubCall.call(currentInstruction[1].u.operand);
    1174 }
    1175 
    1176 void JIT::emit_op_new_regexp(Instruction* currentInstruction)
    1177 {
    1178     JITStubCall stubCall(this, cti_op_new_regexp);
    1179     stubCall.addArgument(ImmPtr(m_codeBlock->regexp(currentInstruction[2].u.operand)));
    11801173    stubCall.call(currentInstruction[1].u.operand);
    11811174}
     
    24472440}
    24482441
    2449 void JIT::emit_op_new_regexp(Instruction* currentInstruction)
    2450 {
    2451     JITStubCall stubCall(this, cti_op_new_regexp);
    2452     stubCall.addArgument(ImmPtr(m_codeBlock->regexp(currentInstruction[2].u.operand)));
    2453     stubCall.call(currentInstruction[1].u.operand);
    2454 }
    2455 
    24562442void JIT::emit_op_bitor(Instruction* currentInstruction)
    24572443{
  • trunk/JavaScriptCore/jit/JITStubs.cpp

    r57192 r57955  
    28592859}
    28602860
    2861 DEFINE_STUB_FUNCTION(JSObject*, op_new_regexp)
    2862 {
    2863     STUB_INIT_STACK_FRAME(stackFrame);
    2864 
    2865     return new (stackFrame.globalData) RegExpObject(stackFrame.callFrame->lexicalGlobalObject()->regExpStructure(), stackFrame.args[0].regExp());
    2866 }
    2867 
    28682861DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitor)
    28692862{
  • trunk/JavaScriptCore/jit/JITStubs.h

    r56842 r57955  
    351351    JSObject* JIT_STUB cti_op_new_func_exp(STUB_ARGS_DECLARATION);
    352352    JSObject* JIT_STUB cti_op_new_object(STUB_ARGS_DECLARATION);
    353     JSObject* JIT_STUB cti_op_new_regexp(STUB_ARGS_DECLARATION);
    354353    JSObject* JIT_STUB cti_op_push_activation(STUB_ARGS_DECLARATION);
    355354    JSObject* JIT_STUB cti_op_push_new_scope(STUB_ARGS_DECLARATION);
Note: See TracChangeset for help on using the changeset viewer.