Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(497)

Side by Side Diff: src/ia32/full-codegen-ia32.cc

Issue 338963003: KeyedLoadIC should have same register spec as LoadIC. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: A bit more refactoring. Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_IA32 7 #if V8_TARGET_ARCH_IA32
8 8
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 1795 matching lines...) Expand 10 before | Expand all | Expand 10 after
1806 1806
1807 // Evaluate LHS expression. 1807 // Evaluate LHS expression.
1808 switch (assign_type) { 1808 switch (assign_type) {
1809 case VARIABLE: 1809 case VARIABLE:
1810 // Nothing to do here. 1810 // Nothing to do here.
1811 break; 1811 break;
1812 case NAMED_PROPERTY: 1812 case NAMED_PROPERTY:
1813 if (expr->is_compound()) { 1813 if (expr->is_compound()) {
1814 // We need the receiver both on the stack and in edx. 1814 // We need the receiver both on the stack and in edx.
1815 VisitForStackValue(property->obj()); 1815 VisitForStackValue(property->obj());
1816 __ mov(edx, Operand(esp, 0)); 1816 __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0));
1817 } else { 1817 } else {
1818 VisitForStackValue(property->obj()); 1818 VisitForStackValue(property->obj());
1819 } 1819 }
1820 break; 1820 break;
1821 case KEYED_PROPERTY: { 1821 case KEYED_PROPERTY: {
1822 if (expr->is_compound()) { 1822 if (expr->is_compound()) {
1823 VisitForStackValue(property->obj()); 1823 VisitForStackValue(property->obj());
1824 VisitForStackValue(property->key()); 1824 VisitForStackValue(property->key());
1825 __ mov(edx, Operand(esp, kPointerSize)); // Object. 1825 __ mov(LoadIC::ReceiverRegister(), Operand(esp, kPointerSize));
1826 __ mov(ecx, Operand(esp, 0)); // Key. 1826 __ mov(LoadIC::NameRegister(), Operand(esp, 0));
1827 } else { 1827 } else {
1828 VisitForStackValue(property->obj()); 1828 VisitForStackValue(property->obj());
1829 VisitForStackValue(property->key()); 1829 VisitForStackValue(property->key());
1830 } 1830 }
1831 break; 1831 break;
1832 } 1832 }
1833 } 1833 }
1834 1834
1835 // For compound assignments we need another deoptimization point after the 1835 // For compound assignments we need another deoptimization point after the
1836 // variable/property load. 1836 // variable/property load.
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1957 1957
1958 case Yield::DELEGATING: { 1958 case Yield::DELEGATING: {
1959 VisitForStackValue(expr->generator_object()); 1959 VisitForStackValue(expr->generator_object());
1960 1960
1961 // Initial stack layout is as follows: 1961 // Initial stack layout is as follows:
1962 // [sp + 1 * kPointerSize] iter 1962 // [sp + 1 * kPointerSize] iter
1963 // [sp + 0 * kPointerSize] g 1963 // [sp + 0 * kPointerSize] g
1964 1964
1965 Label l_catch, l_try, l_suspend, l_continuation, l_resume; 1965 Label l_catch, l_try, l_suspend, l_continuation, l_resume;
1966 Label l_next, l_call, l_loop; 1966 Label l_next, l_call, l_loop;
1967 Register load_receiver = LoadIC::ReceiverRegister();
1968 Register load_name = LoadIC::NameRegister();
1969
1967 // Initial send value is undefined. 1970 // Initial send value is undefined.
1968 __ mov(eax, isolate()->factory()->undefined_value()); 1971 __ mov(eax, isolate()->factory()->undefined_value());
1969 __ jmp(&l_next); 1972 __ jmp(&l_next);
1970 1973
1971 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } 1974 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; }
1972 __ bind(&l_catch); 1975 __ bind(&l_catch);
1973 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); 1976 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
1974 __ mov(ecx, isolate()->factory()->throw_string()); // "throw" 1977 __ mov(load_name, isolate()->factory()->throw_string()); // "throw"
1975 __ push(ecx); // "throw" 1978 __ push(load_name); // "throw"
1976 __ push(Operand(esp, 2 * kPointerSize)); // iter 1979 __ push(Operand(esp, 2 * kPointerSize)); // iter
1977 __ push(eax); // exception 1980 __ push(eax); // exception
1978 __ jmp(&l_call); 1981 __ jmp(&l_call);
1979 1982
1980 // try { received = %yield result } 1983 // try { received = %yield result }
1981 // Shuffle the received result above a try handler and yield it without 1984 // Shuffle the received result above a try handler and yield it without
1982 // re-boxing. 1985 // re-boxing.
1983 __ bind(&l_try); 1986 __ bind(&l_try);
1984 __ pop(eax); // result 1987 __ pop(eax); // result
1985 __ PushTryHandler(StackHandler::CATCH, expr->index()); 1988 __ PushTryHandler(StackHandler::CATCH, expr->index());
1986 const int handler_size = StackHandlerConstants::kSize; 1989 const int handler_size = StackHandlerConstants::kSize;
1987 __ push(eax); // result 1990 __ push(eax); // result
(...skipping 14 matching lines...) Expand all
2002 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 2005 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
2003 __ mov(context_register(), 2006 __ mov(context_register(),
2004 Operand(ebp, StandardFrameConstants::kContextOffset)); 2007 Operand(ebp, StandardFrameConstants::kContextOffset));
2005 __ pop(eax); // result 2008 __ pop(eax); // result
2006 EmitReturnSequence(); 2009 EmitReturnSequence();
2007 __ bind(&l_resume); // received in eax 2010 __ bind(&l_resume); // received in eax
2008 __ PopTryHandler(); 2011 __ PopTryHandler();
2009 2012
2010 // receiver = iter; f = iter.next; arg = received; 2013 // receiver = iter; f = iter.next; arg = received;
2011 __ bind(&l_next); 2014 __ bind(&l_next);
2012 Register keyedload_receiver = KeyedLoadIC::ReceiverRegister();
2013 Register keyedload_name = KeyedLoadIC::NameRegister();
2014 ASSERT(keyedload_receiver.is(edx));
2015 ASSERT(keyedload_name.is(ecx));
2016 2015
2017 __ mov(keyedload_name, 2016 __ mov(load_name, isolate()->factory()->next_string());
2018 isolate()->factory()->next_string()); // "next" 2017 __ push(load_name); // "next"
2019 __ push(keyedload_name); 2018 __ push(Operand(esp, 2 * kPointerSize)); // iter
2020 __ push(Operand(esp, 2 * kPointerSize)); // iter 2019 __ push(eax); // received
2021 __ push(eax); // received
2022 2020
2023 // result = receiver[f](arg); 2021 // result = receiver[f](arg);
2024 __ bind(&l_call); 2022 __ bind(&l_call);
2025 __ mov(keyedload_receiver, Operand(esp, kPointerSize)); 2023 __ mov(load_receiver, Operand(esp, kPointerSize));
2026 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2024 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2027 CallIC(ic, TypeFeedbackId::None()); 2025 CallIC(ic, TypeFeedbackId::None());
2028 __ mov(edi, eax); 2026 __ mov(edi, eax);
2029 __ mov(Operand(esp, 2 * kPointerSize), edi); 2027 __ mov(Operand(esp, 2 * kPointerSize), edi);
2030 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); 2028 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD);
2031 __ CallStub(&stub); 2029 __ CallStub(&stub);
2032 2030
2033 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2031 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2034 __ Drop(1); // The function is still on the stack; drop it. 2032 __ Drop(1); // The function is still on the stack; drop it.
2035 2033
2036 // if (!result.done) goto l_try; 2034 // if (!result.done) goto l_try;
2037 __ bind(&l_loop); 2035 __ bind(&l_loop);
2038 __ push(eax); // save result 2036 __ push(eax); // save result
2039 Register load_receiver = LoadIC::ReceiverRegister(); 2037 ASSERT(!load_receiver.is(eax));
2040 Register load_name = LoadIC::NameRegister();
2041 ASSERT(load_receiver.is(edx));
2042 ASSERT(load_name.is(ecx));
2043 __ mov(load_receiver, eax); // result 2038 __ mov(load_receiver, eax); // result
2044 __ mov(load_name, 2039 __ mov(load_name,
2045 isolate()->factory()->done_string()); // "done" 2040 isolate()->factory()->done_string()); // "done"
2046 CallLoadIC(NOT_CONTEXTUAL); // result.done in eax 2041 CallLoadIC(NOT_CONTEXTUAL); // result.done in eax
2047 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); 2042 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
2048 CallIC(bool_ic); 2043 CallIC(bool_ic);
2049 __ test(eax, eax); 2044 __ test(eax, eax);
2050 __ j(zero, &l_try); 2045 __ j(zero, &l_try);
2051 2046
2052 // result.value 2047 // result.value
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
2503 context()->Plug(eax); 2498 context()->Plug(eax);
2504 } 2499 }
2505 2500
2506 2501
2507 void FullCodeGenerator::VisitProperty(Property* expr) { 2502 void FullCodeGenerator::VisitProperty(Property* expr) {
2508 Comment cmnt(masm_, "[ Property"); 2503 Comment cmnt(masm_, "[ Property");
2509 Expression* key = expr->key(); 2504 Expression* key = expr->key();
2510 2505
2511 if (key->IsPropertyName()) { 2506 if (key->IsPropertyName()) {
2512 VisitForAccumulatorValue(expr->obj()); 2507 VisitForAccumulatorValue(expr->obj());
2508 ASSERT(!result_register().is(LoadIC::ReceiverRegister()));
2513 __ mov(LoadIC::ReceiverRegister(), result_register()); 2509 __ mov(LoadIC::ReceiverRegister(), result_register());
2514 EmitNamedPropertyLoad(expr); 2510 EmitNamedPropertyLoad(expr);
2515 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2511 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
2516 context()->Plug(eax); 2512 context()->Plug(eax);
2517 } else { 2513 } else {
2518 VisitForStackValue(expr->obj()); 2514 VisitForStackValue(expr->obj());
2519 VisitForAccumulatorValue(expr->key()); 2515 VisitForAccumulatorValue(expr->key());
2520 __ pop(KeyedLoadIC::ReceiverRegister()); // Object. 2516 ASSERT(!result_register().is(LoadIC::NameRegister()));
2521 __ mov(KeyedLoadIC::NameRegister(), result_register()); // Key. 2517 __ pop(LoadIC::ReceiverRegister()); // Object.
2518 __ mov(LoadIC::NameRegister(), result_register()); // Key.
2522 EmitKeyedPropertyLoad(expr); 2519 EmitKeyedPropertyLoad(expr);
2523 context()->Plug(eax); 2520 context()->Plug(eax);
2524 } 2521 }
2525 } 2522 }
2526 2523
2527 2524
2528 void FullCodeGenerator::CallIC(Handle<Code> code, 2525 void FullCodeGenerator::CallIC(Handle<Code> code,
2529 TypeFeedbackId ast_id) { 2526 TypeFeedbackId ast_id) {
2530 ic_total_count_++; 2527 ic_total_count_++;
2531 __ call(code, RelocInfo::CODE_TARGET, ast_id); 2528 __ call(code, RelocInfo::CODE_TARGET, ast_id);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2566 // Code common for calls using the IC. 2563 // Code common for calls using the IC.
2567 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2564 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2568 Expression* key) { 2565 Expression* key) {
2569 // Load the key. 2566 // Load the key.
2570 VisitForAccumulatorValue(key); 2567 VisitForAccumulatorValue(key);
2571 2568
2572 Expression* callee = expr->expression(); 2569 Expression* callee = expr->expression();
2573 2570
2574 // Load the function from the receiver. 2571 // Load the function from the receiver.
2575 ASSERT(callee->IsProperty()); 2572 ASSERT(callee->IsProperty());
2576 __ mov(KeyedLoadIC::ReceiverRegister(), Operand(esp, 0)); 2573 __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0));
2577 // Move the key into the right register for the keyed load IC. 2574 // Move the key into the right register for the keyed load IC.
2578 __ mov(KeyedLoadIC::NameRegister(), eax); 2575 __ mov(LoadIC::NameRegister(), eax);
2579 EmitKeyedPropertyLoad(callee->AsProperty()); 2576 EmitKeyedPropertyLoad(callee->AsProperty());
2580 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2577 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2581 2578
2582 // Push the target function under the receiver. 2579 // Push the target function under the receiver.
2583 __ push(Operand(esp, 0)); 2580 __ push(Operand(esp, 0));
2584 __ mov(Operand(esp, kPointerSize), eax); 2581 __ mov(Operand(esp, kPointerSize), eax);
2585 2582
2586 EmitCall(expr, CallIC::METHOD); 2583 EmitCall(expr, CallIC::METHOD);
2587 } 2584 }
2588 2585
(...skipping 1620 matching lines...) Expand 10 before | Expand all | Expand 10 after
4209 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); 4206 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
4210 AccumulatorValueContext context(this); 4207 AccumulatorValueContext context(this);
4211 EmitVariableLoad(expr->expression()->AsVariableProxy()); 4208 EmitVariableLoad(expr->expression()->AsVariableProxy());
4212 } else { 4209 } else {
4213 // Reserve space for result of postfix operation. 4210 // Reserve space for result of postfix operation.
4214 if (expr->is_postfix() && !context()->IsEffect()) { 4211 if (expr->is_postfix() && !context()->IsEffect()) {
4215 __ push(Immediate(Smi::FromInt(0))); 4212 __ push(Immediate(Smi::FromInt(0)));
4216 } 4213 }
4217 if (assign_type == NAMED_PROPERTY) { 4214 if (assign_type == NAMED_PROPERTY) {
4218 // Put the object both on the stack and in edx. 4215 // Put the object both on the stack and in edx.
4219 VisitForAccumulatorValue(prop->obj()); 4216 VisitForStackValue(prop->obj());
4220 ASSERT(!eax.is(LoadIC::ReceiverRegister())); 4217 __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0));
4221 __ push(eax);
4222 __ mov(LoadIC::ReceiverRegister(), eax);
4223 EmitNamedPropertyLoad(prop); 4218 EmitNamedPropertyLoad(prop);
4224 } else { 4219 } else {
4225 VisitForStackValue(prop->obj()); 4220 VisitForStackValue(prop->obj());
4226 VisitForStackValue(prop->key()); 4221 VisitForStackValue(prop->key());
4227 __ mov(KeyedLoadIC::ReceiverRegister(), 4222 __ mov(LoadIC::ReceiverRegister(),
4228 Operand(esp, kPointerSize)); // Object. 4223 Operand(esp, kPointerSize)); // Object.
4229 __ mov(KeyedLoadIC::NameRegister(), Operand(esp, 0)); // Key. 4224 __ mov(LoadIC::NameRegister(), Operand(esp, 0)); // Key.
4230 EmitKeyedPropertyLoad(prop); 4225 EmitKeyedPropertyLoad(prop);
4231 } 4226 }
4232 } 4227 }
4233 4228
4234 // We need a second deoptimization point after loading the value 4229 // We need a second deoptimization point after loading the value
4235 // in case evaluating the property load my have a side effect. 4230 // in case evaluating the property load my have a side effect.
4236 if (assign_type == VARIABLE) { 4231 if (assign_type == VARIABLE) {
4237 PrepareForBailout(expr->expression(), TOS_REG); 4232 PrepareForBailout(expr->expression(), TOS_REG);
4238 } else { 4233 } else {
4239 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 4234 PrepareForBailoutForId(prop->LoadId(), TOS_REG);
(...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after
4811 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), 4806 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(),
4812 Assembler::target_address_at(call_target_address, 4807 Assembler::target_address_at(call_target_address,
4813 unoptimized_code)); 4808 unoptimized_code));
4814 return OSR_AFTER_STACK_CHECK; 4809 return OSR_AFTER_STACK_CHECK;
4815 } 4810 }
4816 4811
4817 4812
4818 } } // namespace v8::internal 4813 } } // namespace v8::internal
4819 4814
4820 #endif // V8_TARGET_ARCH_IA32 4815 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698