Allow inlining of functions containing array literals.

R=yangguo@chromium.org
BUG=v8:1322
TEST=mjsunit/compiler/inline-literals

Review URL: https://chromiumcodereview.appspot.com/10689005

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11942 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 58b89416
...@@ -4754,7 +4754,7 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) { ...@@ -4754,7 +4754,7 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) {
void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
Heap* heap = isolate()->heap(); Handle<FixedArray> literals(instr->environment()->closure()->literals());
ElementsKind boilerplate_elements_kind = ElementsKind boilerplate_elements_kind =
instr->hydrogen()->boilerplate_elements_kind(); instr->hydrogen()->boilerplate_elements_kind();
...@@ -4774,12 +4774,12 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { ...@@ -4774,12 +4774,12 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
DeoptimizeIf(ne, instr->environment()); DeoptimizeIf(ne, instr->environment());
} }
__ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); // Set up the parameters to the stub/runtime call.
__ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset)); __ LoadHeapObject(r3, literals);
__ mov(r2, Operand(Smi::FromInt(instr->hydrogen()->literal_index()))); __ mov(r2, Operand(Smi::FromInt(instr->hydrogen()->literal_index())));
// Boilerplate already exists, constant elements are never accessed. // Boilerplate already exists, constant elements are never accessed.
// Pass an empty fixed array. // 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); __ Push(r3, r2, r1);
// Pick the right runtime function or stub to call. // Pick the right runtime function or stub to call.
......
...@@ -1048,6 +1048,7 @@ REGULAR_NODE(Conditional) ...@@ -1048,6 +1048,7 @@ REGULAR_NODE(Conditional)
REGULAR_NODE(Literal) REGULAR_NODE(Literal)
REGULAR_NODE(ObjectLiteral) REGULAR_NODE(ObjectLiteral)
REGULAR_NODE(RegExpLiteral) REGULAR_NODE(RegExpLiteral)
REGULAR_NODE(ArrayLiteral)
REGULAR_NODE(Assignment) REGULAR_NODE(Assignment)
REGULAR_NODE(Throw) REGULAR_NODE(Throw)
REGULAR_NODE(Property) REGULAR_NODE(Property)
...@@ -1078,7 +1079,6 @@ DONT_OPTIMIZE_NODE(DebuggerStatement) ...@@ -1078,7 +1079,6 @@ DONT_OPTIMIZE_NODE(DebuggerStatement)
DONT_OPTIMIZE_NODE(SharedFunctionInfoLiteral) DONT_OPTIMIZE_NODE(SharedFunctionInfoLiteral)
DONT_INLINE_NODE(FunctionLiteral) DONT_INLINE_NODE(FunctionLiteral)
DONT_INLINE_NODE(ArrayLiteral) // TODO(1322): Allow materialized literals.
DONT_SELFOPTIMIZE_NODE(DoWhileStatement) DONT_SELFOPTIMIZE_NODE(DoWhileStatement)
DONT_SELFOPTIMIZE_NODE(WhileStatement) DONT_SELFOPTIMIZE_NODE(WhileStatement)
......
...@@ -4685,7 +4685,7 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) { ...@@ -4685,7 +4685,7 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) {
void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
ASSERT(ToRegister(instr->context()).is(esi)); ASSERT(ToRegister(instr->context()).is(esi));
Heap* heap = isolate()->heap(); Handle<FixedArray> literals(instr->environment()->closure()->literals());
ElementsKind boilerplate_elements_kind = ElementsKind boilerplate_elements_kind =
instr->hydrogen()->boilerplate_elements_kind(); instr->hydrogen()->boilerplate_elements_kind();
...@@ -4706,12 +4706,11 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { ...@@ -4706,12 +4706,11 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
} }
// Set up the parameters to the stub/runtime call. // Set up the parameters to the stub/runtime call.
__ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); __ PushHeapObject(literals);
__ push(FieldOperand(eax, JSFunction::kLiteralsOffset));
__ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index())));
// Boilerplate already exists, constant elements are never accessed. // Boilerplate already exists, constant elements are never accessed.
// Pass an empty fixed array. // 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. // Pick the right runtime function or stub to call.
int length = instr->hydrogen()->length(); int length = instr->hydrogen()->length();
......
...@@ -4522,7 +4522,7 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) { ...@@ -4522,7 +4522,7 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) {
void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
Heap* heap = isolate()->heap(); Handle<FixedArray> literals(instr->environment()->closure()->literals());
ElementsKind boilerplate_elements_kind = ElementsKind boilerplate_elements_kind =
instr->hydrogen()->boilerplate_elements_kind(); instr->hydrogen()->boilerplate_elements_kind();
...@@ -4543,12 +4543,13 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { ...@@ -4543,12 +4543,13 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
a2, a2,
Operand(boilerplate_elements_kind)); 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()))); __ li(a2, Operand(Smi::FromInt(instr->hydrogen()->literal_index())));
// Boilerplate already exists, constant elements are never accessed. // Boilerplate already exists, constant elements are never accessed.
// Pass an empty fixed array. // 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); __ Push(a3, a2, a1);
// Pick the right runtime function or stub to call. // Pick the right runtime function or stub to call.
......
...@@ -4401,7 +4401,7 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) { ...@@ -4401,7 +4401,7 @@ void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) {
void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
Heap* heap = isolate()->heap(); Handle<FixedArray> literals(instr->environment()->closure()->literals());
ElementsKind boilerplate_elements_kind = ElementsKind boilerplate_elements_kind =
instr->hydrogen()->boilerplate_elements_kind(); instr->hydrogen()->boilerplate_elements_kind();
...@@ -4422,12 +4422,11 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { ...@@ -4422,12 +4422,11 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
} }
// Set up the parameters to the stub/runtime call. // Set up the parameters to the stub/runtime call.
__ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); __ PushHeapObject(literals);
__ push(FieldOperand(rax, JSFunction::kLiteralsOffset));
__ Push(Smi::FromInt(instr->hydrogen()->literal_index())); __ Push(Smi::FromInt(instr->hydrogen()->literal_index()));
// Boilerplate already exists, constant elements are never accessed. // Boilerplate already exists, constant elements are never accessed.
// Pass an empty fixed array. // 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. // Pick the right runtime function or stub to call.
int length = instr->hydrogen()->length(); int length = instr->hydrogen()->length();
......
...@@ -29,6 +29,26 @@ ...@@ -29,6 +29,26 @@
// Test that we can inline functions containing materialized literals. // 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) { function o2(b, c) {
return { 'b':b, 'c':c, 'y':b + c }; return { 'b':b, 'c':c, 'y':b + c };
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment