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

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: Last comment response. 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
« no previous file with comments | « src/ia32/debug-ia32.cc ('k') | src/ia32/ic-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1793 matching lines...) Expand 10 before | Expand all | Expand 10 after
1804 : KEYED_PROPERTY; 1804 : KEYED_PROPERTY;
1805 } 1805 }
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 the register.
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 __ Move(load_receiver, eax); // result
2040 Register load_name = LoadIC::NameRegister();
2041 ASSERT(load_receiver.is(edx));
2042 ASSERT(load_name.is(ecx));
2043 __ mov(load_receiver, eax); // result
2044 __ mov(load_name, 2038 __ mov(load_name,
2045 isolate()->factory()->done_string()); // "done" 2039 isolate()->factory()->done_string()); // "done"
2046 CallLoadIC(NOT_CONTEXTUAL); // result.done in eax 2040 CallLoadIC(NOT_CONTEXTUAL); // result.done in eax
2047 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); 2041 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
2048 CallIC(bool_ic); 2042 CallIC(bool_ic);
2049 __ test(eax, eax); 2043 __ test(eax, eax);
2050 __ j(zero, &l_try); 2044 __ j(zero, &l_try);
2051 2045
2052 // result.value 2046 // result.value
2053 __ pop(load_receiver); // result 2047 __ pop(load_receiver); // result
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
2503 context()->Plug(eax); 2497 context()->Plug(eax);
2504 } 2498 }
2505 2499
2506 2500
2507 void FullCodeGenerator::VisitProperty(Property* expr) { 2501 void FullCodeGenerator::VisitProperty(Property* expr) {
2508 Comment cmnt(masm_, "[ Property"); 2502 Comment cmnt(masm_, "[ Property");
2509 Expression* key = expr->key(); 2503 Expression* key = expr->key();
2510 2504
2511 if (key->IsPropertyName()) { 2505 if (key->IsPropertyName()) {
2512 VisitForAccumulatorValue(expr->obj()); 2506 VisitForAccumulatorValue(expr->obj());
2513 __ mov(LoadIC::ReceiverRegister(), result_register()); 2507 __ Move(LoadIC::ReceiverRegister(), result_register());
2514 EmitNamedPropertyLoad(expr); 2508 EmitNamedPropertyLoad(expr);
2515 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2509 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
2516 context()->Plug(eax); 2510 context()->Plug(eax);
2517 } else { 2511 } else {
2518 VisitForStackValue(expr->obj()); 2512 VisitForStackValue(expr->obj());
2519 VisitForAccumulatorValue(expr->key()); 2513 VisitForAccumulatorValue(expr->key());
2520 __ pop(KeyedLoadIC::ReceiverRegister()); // Object. 2514 __ pop(LoadIC::ReceiverRegister()); // Object.
2521 __ mov(KeyedLoadIC::NameRegister(), result_register()); // Key. 2515 __ Move(LoadIC::NameRegister(), result_register()); // Key.
2522 EmitKeyedPropertyLoad(expr); 2516 EmitKeyedPropertyLoad(expr);
2523 context()->Plug(eax); 2517 context()->Plug(eax);
2524 } 2518 }
2525 } 2519 }
2526 2520
2527 2521
2528 void FullCodeGenerator::CallIC(Handle<Code> code, 2522 void FullCodeGenerator::CallIC(Handle<Code> code,
2529 TypeFeedbackId ast_id) { 2523 TypeFeedbackId ast_id) {
2530 ic_total_count_++; 2524 ic_total_count_++;
2531 __ call(code, RelocInfo::CODE_TARGET, ast_id); 2525 __ 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. 2560 // Code common for calls using the IC.
2567 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2561 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2568 Expression* key) { 2562 Expression* key) {
2569 // Load the key. 2563 // Load the key.
2570 VisitForAccumulatorValue(key); 2564 VisitForAccumulatorValue(key);
2571 2565
2572 Expression* callee = expr->expression(); 2566 Expression* callee = expr->expression();
2573 2567
2574 // Load the function from the receiver. 2568 // Load the function from the receiver.
2575 ASSERT(callee->IsProperty()); 2569 ASSERT(callee->IsProperty());
2576 __ mov(KeyedLoadIC::ReceiverRegister(), Operand(esp, 0)); 2570 __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0));
2577 // Move the key into the right register for the keyed load IC. 2571 __ mov(LoadIC::NameRegister(), eax);
2578 __ mov(KeyedLoadIC::NameRegister(), eax);
2579 EmitKeyedPropertyLoad(callee->AsProperty()); 2572 EmitKeyedPropertyLoad(callee->AsProperty());
2580 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2573 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2581 2574
2582 // Push the target function under the receiver. 2575 // Push the target function under the receiver.
2583 __ push(Operand(esp, 0)); 2576 __ push(Operand(esp, 0));
2584 __ mov(Operand(esp, kPointerSize), eax); 2577 __ mov(Operand(esp, kPointerSize), eax);
2585 2578
2586 EmitCall(expr, CallIC::METHOD); 2579 EmitCall(expr, CallIC::METHOD);
2587 } 2580 }
2588 2581
(...skipping 1619 matching lines...) Expand 10 before | Expand all | Expand 10 after
4208 if (assign_type == VARIABLE) { 4201 if (assign_type == VARIABLE) {
4209 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); 4202 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
4210 AccumulatorValueContext context(this); 4203 AccumulatorValueContext context(this);
4211 EmitVariableLoad(expr->expression()->AsVariableProxy()); 4204 EmitVariableLoad(expr->expression()->AsVariableProxy());
4212 } else { 4205 } else {
4213 // Reserve space for result of postfix operation. 4206 // Reserve space for result of postfix operation.
4214 if (expr->is_postfix() && !context()->IsEffect()) { 4207 if (expr->is_postfix() && !context()->IsEffect()) {
4215 __ push(Immediate(Smi::FromInt(0))); 4208 __ push(Immediate(Smi::FromInt(0)));
4216 } 4209 }
4217 if (assign_type == NAMED_PROPERTY) { 4210 if (assign_type == NAMED_PROPERTY) {
4218 // Put the object both on the stack and in edx. 4211 // Put the object both on the stack and in the register.
4219 VisitForAccumulatorValue(prop->obj()); 4212 VisitForStackValue(prop->obj());
4220 ASSERT(!eax.is(LoadIC::ReceiverRegister())); 4213 __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0));
4221 __ push(eax);
4222 __ mov(LoadIC::ReceiverRegister(), eax);
4223 EmitNamedPropertyLoad(prop); 4214 EmitNamedPropertyLoad(prop);
4224 } else { 4215 } else {
4225 VisitForStackValue(prop->obj()); 4216 VisitForStackValue(prop->obj());
4226 VisitForStackValue(prop->key()); 4217 VisitForStackValue(prop->key());
4227 __ mov(KeyedLoadIC::ReceiverRegister(), 4218 __ mov(LoadIC::ReceiverRegister(),
4228 Operand(esp, kPointerSize)); // Object. 4219 Operand(esp, kPointerSize)); // Object.
4229 __ mov(KeyedLoadIC::NameRegister(), Operand(esp, 0)); // Key. 4220 __ mov(LoadIC::NameRegister(), Operand(esp, 0)); // Key.
4230 EmitKeyedPropertyLoad(prop); 4221 EmitKeyedPropertyLoad(prop);
4231 } 4222 }
4232 } 4223 }
4233 4224
4234 // We need a second deoptimization point after loading the value 4225 // We need a second deoptimization point after loading the value
4235 // in case evaluating the property load my have a side effect. 4226 // in case evaluating the property load my have a side effect.
4236 if (assign_type == VARIABLE) { 4227 if (assign_type == VARIABLE) {
4237 PrepareForBailout(expr->expression(), TOS_REG); 4228 PrepareForBailout(expr->expression(), TOS_REG);
4238 } else { 4229 } else {
4239 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 4230 PrepareForBailoutForId(prop->LoadId(), TOS_REG);
(...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after
4811 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), 4802 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(),
4812 Assembler::target_address_at(call_target_address, 4803 Assembler::target_address_at(call_target_address,
4813 unoptimized_code)); 4804 unoptimized_code));
4814 return OSR_AFTER_STACK_CHECK; 4805 return OSR_AFTER_STACK_CHECK;
4815 } 4806 }
4816 4807
4817 4808
4818 } } // namespace v8::internal 4809 } } // namespace v8::internal
4819 4810
4820 #endif // V8_TARGET_ARCH_IA32 4811 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/debug-ia32.cc ('k') | src/ia32/ic-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698