Reviewers: Yang,

Description:
Allow inlining of functions containing array literals.

[email protected]
BUG=v8:1322
TEST=mjsunit/compiler/inline-literals


Please review this at https://chromiumcodereview.appspot.com/10689005/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/arm/lithium-codegen-arm.cc
  M src/ast.cc
  M src/ia32/lithium-codegen-ia32.cc
  M src/mips/lithium-codegen-mips.cc
  M src/x64/lithium-codegen-x64.cc
  M test/mjsunit/compiler/inline-literals.js


Index: src/arm/lithium-codegen-arm.cc
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index a61e4c0c5144e21f6f062b550f142ead8caa88e4..e0633d5420bcd6b35041a20e14c8aa876853c9af 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -4754,7 +4754,7 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) {


 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
-  Heap* heap = isolate()->heap();
+  Handle<FixedArray> literals(instr->environment()->closure()->literals());
   ElementsKind boilerplate_elements_kind =
       instr->hydrogen()->boilerplate_elements_kind();

@@ -4774,12 +4774,12 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
     DeoptimizeIf(ne, instr->environment());
   }

-  __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
-  __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset));
+  // Set up the parameters to the stub/runtime call.
+  __ LoadHeapObject(r3, literals);
   __ mov(r2, Operand(Smi::FromInt(instr->hydrogen()->literal_index())));
   // Boilerplate already exists, constant elements are never accessed.
   // Pass an empty fixed array.
-  __ mov(r1, Operand(Handle<FixedArray>(heap->empty_fixed_array())));
+  __ mov(r1, Operand(isolate()->factory()->empty_fixed_array()));
   __ Push(r3, r2, r1);

   // Pick the right runtime function or stub to call.
Index: src/ast.cc
diff --git a/src/ast.cc b/src/ast.cc
index 013c6331da4ccf994bff6134fe2cec3e6b44659f..8ac139fe85cca56263b2ea5b80d803baff69975a 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -1048,6 +1048,7 @@ REGULAR_NODE(Conditional)
 REGULAR_NODE(Literal)
 REGULAR_NODE(ObjectLiteral)
 REGULAR_NODE(RegExpLiteral)
+REGULAR_NODE(ArrayLiteral)
 REGULAR_NODE(Assignment)
 REGULAR_NODE(Throw)
 REGULAR_NODE(Property)
@@ -1078,7 +1079,6 @@ DONT_OPTIMIZE_NODE(DebuggerStatement)
 DONT_OPTIMIZE_NODE(SharedFunctionInfoLiteral)

 DONT_INLINE_NODE(FunctionLiteral)
-DONT_INLINE_NODE(ArrayLiteral)  // TODO(1322): Allow materialized literals.

 DONT_SELFOPTIMIZE_NODE(DoWhileStatement)
 DONT_SELFOPTIMIZE_NODE(WhileStatement)
Index: src/ia32/lithium-codegen-ia32.cc
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index 9cc67a308af2584cdce9d649b8fb02294f68b829..48cd780c6a43ec3a4ebb57f0fc4a54663d8896ac 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -4685,7 +4685,7 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) {

 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
   ASSERT(ToRegister(instr->context()).is(esi));
-  Heap* heap = isolate()->heap();
+  Handle<FixedArray> literals(instr->environment()->closure()->literals());
   ElementsKind boilerplate_elements_kind =
       instr->hydrogen()->boilerplate_elements_kind();

@@ -4706,12 +4706,11 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
   }

   // Set up the parameters to the stub/runtime call.
-  __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
-  __ push(FieldOperand(eax, JSFunction::kLiteralsOffset));
+  __ PushHeapObject(literals);
   __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index())));
   // Boilerplate already exists, constant elements are never accessed.
   // Pass an empty fixed array.
-  __ push(Immediate(Handle<FixedArray>(heap->empty_fixed_array())));
+  __ push(Immediate(isolate()->factory()->empty_fixed_array()));

   // Pick the right runtime function or stub to call.
   int length = instr->hydrogen()->length();
Index: src/mips/lithium-codegen-mips.cc
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index 60df710dbf119e043db163cc13a01e6fae54e156..a992799502210acc6cfb3445617ed97afcbb6b8b 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -4522,7 +4522,7 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) {


 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
-  Heap* heap = isolate()->heap();
+  Handle<FixedArray> literals(instr->environment()->closure()->literals());
   ElementsKind boilerplate_elements_kind =
       instr->hydrogen()->boilerplate_elements_kind();

@@ -4543,12 +4543,13 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
                  a2,
                  Operand(boilerplate_elements_kind));
   }
-  __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
-  __ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset));
+
+  // Set up the parameters to the stub/runtime call.
+  __ LoadHeapObject(a3, literals);
   __ li(a2, Operand(Smi::FromInt(instr->hydrogen()->literal_index())));
   // Boilerplate already exists, constant elements are never accessed.
   // Pass an empty fixed array.
-  __ li(a1, Operand(Handle<FixedArray>(heap->empty_fixed_array())));
+  __ li(a1, Operand(isolate()->factory()->empty_fixed_array()));
   __ Push(a3, a2, a1);

   // Pick the right runtime function or stub to call.
Index: src/x64/lithium-codegen-x64.cc
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 77cb75dbf243586beab9b83f9d5a142cced922e8..a19fcec3b91ae03254b2c764c93cdd16acb99628 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -4401,7 +4401,7 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) {


 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
-  Heap* heap = isolate()->heap();
+  Handle<FixedArray> literals(instr->environment()->closure()->literals());
   ElementsKind boilerplate_elements_kind =
       instr->hydrogen()->boilerplate_elements_kind();

@@ -4422,12 +4422,11 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
   }

   // Set up the parameters to the stub/runtime call.
-  __ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
-  __ push(FieldOperand(rax, JSFunction::kLiteralsOffset));
+  __ PushHeapObject(literals);
   __ Push(Smi::FromInt(instr->hydrogen()->literal_index()));
   // Boilerplate already exists, constant elements are never accessed.
   // Pass an empty fixed array.
-  __ Push(Handle<FixedArray>(heap->empty_fixed_array()));
+  __ Push(isolate()->factory()->empty_fixed_array());

   // Pick the right runtime function or stub to call.
   int length = instr->hydrogen()->length();
Index: test/mjsunit/compiler/inline-literals.js
diff --git a/test/mjsunit/compiler/inline-literals.js b/test/mjsunit/compiler/inline-literals.js index ece1ad7a25ae24bd6fb3e364adbb87801f26a393..1422586912be98209b9facbfe3db88fa7b56eb14 100644
--- a/test/mjsunit/compiler/inline-literals.js
+++ b/test/mjsunit/compiler/inline-literals.js
@@ -29,6 +29,26 @@

 // Test that we can inline functions containing materialized literals.

+function a2(b, c) {
+  return [b, c, b + c];
+}
+
+function a1(a, b, c) {
+  return [a, a2(b, c)];
+}
+
+function TestArrayLiteral(a, b, c) {
+  var expected = [a, [b, c, b + c]];
+  var result = a1(a, b, c);
+  assertEquals(expected, result, "TestArrayLiteral");
+}
+
+TestArrayLiteral(1, 2, 3);
+TestArrayLiteral(1, 2, 3);
+%OptimizeFunctionOnNextCall(TestArrayLiteral);
+TestArrayLiteral(1, 2, 3);
+TestArrayLiteral('a', 'b', 'c');
+
 function o2(b, c) {
   return { 'b':b, 'c':c, 'y':b + c };
 }


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to