From df35732ab220bbcfbae1b8f84cdc18f10ce4c2f9 Mon Sep 17 00:00:00 2001 From: "mstarzinger@chromium.org" Date: Wed, 27 Jun 2012 11:49:37 +0000 Subject: [PATCH] Allow inlining of functions containing RegExp literals. R=yangguo@chromium.org BUG=v8:1322 TEST=mjsunit/compiler/inline-literals Review URL: https://chromiumcodereview.appspot.com/10703005 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11940 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/lithium-codegen-arm.cc | 8 +++----- src/ast.cc | 2 +- src/hydrogen-instructions.h | 4 ++++ src/hydrogen.cc | 3 +++ src/ia32/lithium-codegen-ia32.cc | 8 +++----- src/mips/lithium-codegen-mips.cc | 8 +++----- src/objects-printer.cc | 2 ++ src/x64/lithium-codegen-x64.cc | 8 +++----- test/mjsunit/compiler/inline-literals.js | 19 +++++++++++++++++++ 9 files changed, 41 insertions(+), 21 deletions(-) diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index 8cef74d..a61e4c0 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -4987,15 +4987,13 @@ void LCodeGen::DoToFastProperties(LToFastProperties* instr) { void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { Label materialized; // Registers will be used as follows: - // r3 = JS function. // r7 = literals array. // r1 = regexp literal. // r0 = regexp literal clone. // r2 and r4-r6 are used as temporaries. - __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); - __ ldr(r7, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); - int literal_offset = FixedArray::kHeaderSize + - instr->hydrogen()->literal_index() * kPointerSize; + int literal_offset = + FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index()); + __ LoadHeapObject(r7, instr->hydrogen()->literals()); __ ldr(r1, FieldMemOperand(r7, literal_offset)); __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); __ cmp(r1, ip); diff --git a/src/ast.cc b/src/ast.cc index fb9db7c..013c633 100644 --- a/src/ast.cc +++ b/src/ast.cc @@ -1047,6 +1047,7 @@ REGULAR_NODE(SwitchStatement) REGULAR_NODE(Conditional) REGULAR_NODE(Literal) REGULAR_NODE(ObjectLiteral) +REGULAR_NODE(RegExpLiteral) REGULAR_NODE(Assignment) REGULAR_NODE(Throw) REGULAR_NODE(Property) @@ -1077,7 +1078,6 @@ DONT_OPTIMIZE_NODE(DebuggerStatement) DONT_OPTIMIZE_NODE(SharedFunctionInfoLiteral) DONT_INLINE_NODE(FunctionLiteral) -DONT_INLINE_NODE(RegExpLiteral) // TODO(1322): Allow materialized literals. DONT_INLINE_NODE(ArrayLiteral) // TODO(1322): Allow materialized literals. DONT_SELFOPTIMIZE_NODE(DoWhileStatement) diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index e0c443a..e92d747 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -4792,10 +4792,12 @@ class HObjectLiteral: public HMaterializedLiteral<1> { class HRegExpLiteral: public HMaterializedLiteral<1> { public: HRegExpLiteral(HValue* context, + Handle literals, Handle pattern, Handle flags, int literal_index) : HMaterializedLiteral<1>(literal_index, 0), + literals_(literals), pattern_(pattern), flags_(flags) { SetOperandAt(0, context); @@ -4803,6 +4805,7 @@ class HRegExpLiteral: public HMaterializedLiteral<1> { } HValue* context() { return OperandAt(0); } + Handle literals() { return literals_; } Handle pattern() { return pattern_; } Handle flags() { return flags_; } @@ -4814,6 +4817,7 @@ class HRegExpLiteral: public HMaterializedLiteral<1> { DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral) private: + Handle literals_; Handle pattern_; Handle flags_; }; diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 16e7a0c..a1ec78e 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -4647,9 +4647,12 @@ void HGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { ASSERT(!HasStackOverflow()); ASSERT(current_block() != NULL); ASSERT(current_block()->HasPredecessor()); + Handle closure = function_state()->compilation_info()->closure(); + Handle literals(closure->literals()); HValue* context = environment()->LookupContext(); HRegExpLiteral* instr = new(zone()) HRegExpLiteral(context, + literals, expr->pattern(), expr->flags(), expr->literal_index()); diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index e27a326..9cc67a3 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -4930,15 +4930,13 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { ASSERT(ToRegister(instr->context()).is(esi)); Label materialized; // Registers will be used as follows: - // edi = JS function. // ecx = literals array. // ebx = regexp literal. // eax = regexp literal clone. // esi = context. - __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); - __ mov(ecx, FieldOperand(edi, JSFunction::kLiteralsOffset)); - int literal_offset = FixedArray::kHeaderSize + - instr->hydrogen()->literal_index() * kPointerSize; + int literal_offset = + FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index()); + __ LoadHeapObject(ecx, instr->hydrogen()->literals()); __ mov(ebx, FieldOperand(ecx, literal_offset)); __ cmp(ebx, factory()->undefined_value()); __ j(not_equal, &materialized, Label::kNear); diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index 584fd7a..60df710 100644 --- a/src/mips/lithium-codegen-mips.cc +++ b/src/mips/lithium-codegen-mips.cc @@ -4759,15 +4759,13 @@ void LCodeGen::DoToFastProperties(LToFastProperties* instr) { void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { Label materialized; // Registers will be used as follows: - // a3 = JS function. // t3 = literals array. // a1 = regexp literal. // a0 = regexp literal clone. // a2 and t0-t2 are used as temporaries. - __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); - __ lw(t3, FieldMemOperand(a3, JSFunction::kLiteralsOffset)); - int literal_offset = FixedArray::kHeaderSize + - instr->hydrogen()->literal_index() * kPointerSize; + int literal_offset = + FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index()); + __ LoadHeapObject(t3, instr->hydrogen()->literals()); __ lw(a1, FieldMemOperand(t3, literal_offset)); __ LoadRoot(at, Heap::kUndefinedValueRootIndex); __ Branch(&materialized, ne, a1, Operand(at)); diff --git a/src/objects-printer.cc b/src/objects-printer.cc index ac3765e..2e58c09 100644 --- a/src/objects-printer.cc +++ b/src/objects-printer.cc @@ -739,6 +739,8 @@ void JSFunction::JSFunctionPrint(FILE* out) { shared()->name()->Print(out); PrintF(out, "\n - context = "); unchecked_context()->ShortPrint(out); + PrintF(out, "\n - literals = "); + literals()->ShortPrint(out); PrintF(out, "\n - code = "); code()->ShortPrint(out); PrintF(out, "\n"); diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index 808c4d8..77cb75d 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -4630,14 +4630,12 @@ void LCodeGen::DoToFastProperties(LToFastProperties* instr) { void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { Label materialized; // Registers will be used as follows: - // rdi = JS function. // rcx = literals array. // rbx = regexp literal. // rax = regexp literal clone. - __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); - __ movq(rcx, FieldOperand(rdi, JSFunction::kLiteralsOffset)); - int literal_offset = FixedArray::kHeaderSize + - instr->hydrogen()->literal_index() * kPointerSize; + int literal_offset = + FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index()); + __ LoadHeapObject(rcx, instr->hydrogen()->literals()); __ movq(rbx, FieldOperand(rcx, literal_offset)); __ CompareRoot(rbx, Heap::kUndefinedValueRootIndex); __ j(not_equal, &materialized, Label::kNear); diff --git a/test/mjsunit/compiler/inline-literals.js b/test/mjsunit/compiler/inline-literals.js index f78abe8..ece1ad7 100644 --- a/test/mjsunit/compiler/inline-literals.js +++ b/test/mjsunit/compiler/inline-literals.js @@ -48,3 +48,22 @@ TestObjectLiteral(1, 2, 3); %OptimizeFunctionOnNextCall(TestObjectLiteral); TestObjectLiteral(1, 2, 3); TestObjectLiteral('a', 'b', 'c'); + +function r2(s, x, y) { + return s.replace(/a/, x + y); +} + +function r1(s, x, y) { + return r2(s, x, y).replace(/b/, y + x); +} + +function TestRegExpLiteral(s, x, y, expected) { + var result = r1(s, x, y); + assertEquals(expected, result, "TestRegExpLiteral"); +} + +TestRegExpLiteral("a-", "reg", "exp", "regexp-"); +TestRegExpLiteral("-b", "reg", "exp", "-expreg"); +%OptimizeFunctionOnNextCall(TestRegExpLiteral); +TestRegExpLiteral("ab", "reg", "exp", "regexpexpreg"); +TestRegExpLiteral("ab", 12345, 54321, "6666666666"); -- 2.7.4