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

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

Issue 366583002: X87: KeyedLoadIC should have same register spec as LoadIC. (Closed) Base URL: https://github.com/v8/v8.git@master
Patch Set: 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
« no previous file with comments | « src/x87/debug-x87.cc ('k') | src/x87/ic-x87.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_X87 7 #if V8_TARGET_ARCH_X87
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 1789 matching lines...) Expand 10 before | Expand all | Expand 10 after
1800 : KEYED_PROPERTY; 1800 : KEYED_PROPERTY;
1801 } 1801 }
1802 1802
1803 // Evaluate LHS expression. 1803 // Evaluate LHS expression.
1804 switch (assign_type) { 1804 switch (assign_type) {
1805 case VARIABLE: 1805 case VARIABLE:
1806 // Nothing to do here. 1806 // Nothing to do here.
1807 break; 1807 break;
1808 case NAMED_PROPERTY: 1808 case NAMED_PROPERTY:
1809 if (expr->is_compound()) { 1809 if (expr->is_compound()) {
1810 // We need the receiver both on the stack and in edx. 1810 // We need the receiver both on the stack and in the register.
1811 VisitForStackValue(property->obj()); 1811 VisitForStackValue(property->obj());
1812 __ mov(edx, Operand(esp, 0)); 1812 __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0));
1813 } else { 1813 } else {
1814 VisitForStackValue(property->obj()); 1814 VisitForStackValue(property->obj());
1815 } 1815 }
1816 break; 1816 break;
1817 case KEYED_PROPERTY: { 1817 case KEYED_PROPERTY: {
1818 if (expr->is_compound()) { 1818 if (expr->is_compound()) {
1819 VisitForStackValue(property->obj()); 1819 VisitForStackValue(property->obj());
1820 VisitForStackValue(property->key()); 1820 VisitForStackValue(property->key());
1821 __ mov(edx, Operand(esp, kPointerSize)); // Object. 1821 __ mov(LoadIC::ReceiverRegister(), Operand(esp, kPointerSize));
1822 __ mov(ecx, Operand(esp, 0)); // Key. 1822 __ mov(LoadIC::NameRegister(), Operand(esp, 0));
1823 } else { 1823 } else {
1824 VisitForStackValue(property->obj()); 1824 VisitForStackValue(property->obj());
1825 VisitForStackValue(property->key()); 1825 VisitForStackValue(property->key());
1826 } 1826 }
1827 break; 1827 break;
1828 } 1828 }
1829 } 1829 }
1830 1830
1831 // For compound assignments we need another deoptimization point after the 1831 // For compound assignments we need another deoptimization point after the
1832 // variable/property load. 1832 // variable/property load.
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1952 1952
1953 case Yield::DELEGATING: { 1953 case Yield::DELEGATING: {
1954 VisitForStackValue(expr->generator_object()); 1954 VisitForStackValue(expr->generator_object());
1955 1955
1956 // Initial stack layout is as follows: 1956 // Initial stack layout is as follows:
1957 // [sp + 1 * kPointerSize] iter 1957 // [sp + 1 * kPointerSize] iter
1958 // [sp + 0 * kPointerSize] g 1958 // [sp + 0 * kPointerSize] g
1959 1959
1960 Label l_catch, l_try, l_suspend, l_continuation, l_resume; 1960 Label l_catch, l_try, l_suspend, l_continuation, l_resume;
1961 Label l_next, l_call, l_loop; 1961 Label l_next, l_call, l_loop;
1962 Register load_receiver = LoadIC::ReceiverRegister();
1963 Register load_name = LoadIC::NameRegister();
1964
1962 // Initial send value is undefined. 1965 // Initial send value is undefined.
1963 __ mov(eax, isolate()->factory()->undefined_value()); 1966 __ mov(eax, isolate()->factory()->undefined_value());
1964 __ jmp(&l_next); 1967 __ jmp(&l_next);
1965 1968
1966 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } 1969 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; }
1967 __ bind(&l_catch); 1970 __ bind(&l_catch);
1968 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); 1971 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
1969 __ mov(ecx, isolate()->factory()->throw_string()); // "throw" 1972 __ mov(load_name, isolate()->factory()->throw_string()); // "throw"
1970 __ push(ecx); // "throw" 1973 __ push(load_name); // "throw"
1971 __ push(Operand(esp, 2 * kPointerSize)); // iter 1974 __ push(Operand(esp, 2 * kPointerSize)); // iter
1972 __ push(eax); // exception 1975 __ push(eax); // exception
1973 __ jmp(&l_call); 1976 __ jmp(&l_call);
1974 1977
1975 // try { received = %yield result } 1978 // try { received = %yield result }
1976 // Shuffle the received result above a try handler and yield it without 1979 // Shuffle the received result above a try handler and yield it without
1977 // re-boxing. 1980 // re-boxing.
1978 __ bind(&l_try); 1981 __ bind(&l_try);
1979 __ pop(eax); // result 1982 __ pop(eax); // result
1980 __ PushTryHandler(StackHandler::CATCH, expr->index()); 1983 __ PushTryHandler(StackHandler::CATCH, expr->index());
1981 const int handler_size = StackHandlerConstants::kSize; 1984 const int handler_size = StackHandlerConstants::kSize;
1982 __ push(eax); // result 1985 __ push(eax); // result
(...skipping 13 matching lines...) Expand all
1996 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 1999 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1997 __ mov(context_register(), 2000 __ mov(context_register(),
1998 Operand(ebp, StandardFrameConstants::kContextOffset)); 2001 Operand(ebp, StandardFrameConstants::kContextOffset));
1999 __ pop(eax); // result 2002 __ pop(eax); // result
2000 EmitReturnSequence(); 2003 EmitReturnSequence();
2001 __ bind(&l_resume); // received in eax 2004 __ bind(&l_resume); // received in eax
2002 __ PopTryHandler(); 2005 __ PopTryHandler();
2003 2006
2004 // receiver = iter; f = iter.next; arg = received; 2007 // receiver = iter; f = iter.next; arg = received;
2005 __ bind(&l_next); 2008 __ bind(&l_next);
2006 Register keyedload_receiver = KeyedLoadIC::ReceiverRegister();
2007 Register keyedload_name = KeyedLoadIC::NameRegister();
2008 ASSERT(keyedload_receiver.is(edx));
2009 ASSERT(keyedload_name.is(ecx));
2010 2009
2011 __ mov(keyedload_name, 2010 __ mov(load_name, isolate()->factory()->next_string());
2012 isolate()->factory()->next_string()); // "next" 2011 __ push(load_name); // "next"
2013 __ push(keyedload_name); 2012 __ push(Operand(esp, 2 * kPointerSize)); // iter
2014 __ push(Operand(esp, 2 * kPointerSize)); // iter 2013 __ push(eax); // received
2015 __ push(eax); // received
2016 2014
2017 // result = receiver[f](arg); 2015 // result = receiver[f](arg);
2018 __ bind(&l_call); 2016 __ bind(&l_call);
2019 __ mov(keyedload_receiver, Operand(esp, kPointerSize)); 2017 __ mov(load_receiver, Operand(esp, kPointerSize));
2020 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2018 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2021 CallIC(ic, TypeFeedbackId::None()); 2019 CallIC(ic, TypeFeedbackId::None());
2022 __ mov(edi, eax); 2020 __ mov(edi, eax);
2023 __ mov(Operand(esp, 2 * kPointerSize), edi); 2021 __ mov(Operand(esp, 2 * kPointerSize), edi);
2024 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); 2022 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD);
2025 __ CallStub(&stub); 2023 __ CallStub(&stub);
2026 2024
2027 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2025 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2028 __ Drop(1); // The function is still on the stack; drop it. 2026 __ Drop(1); // The function is still on the stack; drop it.
2029 2027
2030 // if (!result.done) goto l_try; 2028 // if (!result.done) goto l_try;
2031 __ bind(&l_loop); 2029 __ bind(&l_loop);
2032 __ push(eax); // save result 2030 __ push(eax); // save result
2033 Register load_receiver = LoadIC::ReceiverRegister(); 2031 __ Move(load_receiver, eax); // result
2034 Register load_name = LoadIC::NameRegister();
2035 ASSERT(load_receiver.is(edx));
2036 ASSERT(load_name.is(ecx));
2037 __ mov(load_receiver, eax); // result
2038 __ mov(load_name, 2032 __ mov(load_name,
2039 isolate()->factory()->done_string()); // "done" 2033 isolate()->factory()->done_string()); // "done"
2040 CallLoadIC(NOT_CONTEXTUAL); // result.done in eax 2034 CallLoadIC(NOT_CONTEXTUAL); // result.done in eax
2041 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); 2035 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
2042 CallIC(bool_ic); 2036 CallIC(bool_ic);
2043 __ test(eax, eax); 2037 __ test(eax, eax);
2044 __ j(zero, &l_try); 2038 __ j(zero, &l_try);
2045 2039
2046 // result.value 2040 // result.value
2047 __ pop(load_receiver); // result 2041 __ pop(load_receiver); // result
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
2497 context()->Plug(eax); 2491 context()->Plug(eax);
2498 } 2492 }
2499 2493
2500 2494
2501 void FullCodeGenerator::VisitProperty(Property* expr) { 2495 void FullCodeGenerator::VisitProperty(Property* expr) {
2502 Comment cmnt(masm_, "[ Property"); 2496 Comment cmnt(masm_, "[ Property");
2503 Expression* key = expr->key(); 2497 Expression* key = expr->key();
2504 2498
2505 if (key->IsPropertyName()) { 2499 if (key->IsPropertyName()) {
2506 VisitForAccumulatorValue(expr->obj()); 2500 VisitForAccumulatorValue(expr->obj());
2507 __ mov(LoadIC::ReceiverRegister(), result_register()); 2501 __ Move(LoadIC::ReceiverRegister(), result_register());
2508 EmitNamedPropertyLoad(expr); 2502 EmitNamedPropertyLoad(expr);
2509 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2503 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
2510 context()->Plug(eax); 2504 context()->Plug(eax);
2511 } else { 2505 } else {
2512 VisitForStackValue(expr->obj()); 2506 VisitForStackValue(expr->obj());
2513 VisitForAccumulatorValue(expr->key()); 2507 VisitForAccumulatorValue(expr->key());
2514 __ pop(KeyedLoadIC::ReceiverRegister()); // Object. 2508 __ pop(LoadIC::ReceiverRegister()); // Object.
2515 __ mov(KeyedLoadIC::NameRegister(), result_register()); // Key. 2509 __ Move(LoadIC::NameRegister(), result_register()); // Key.
2516 EmitKeyedPropertyLoad(expr); 2510 EmitKeyedPropertyLoad(expr);
2517 context()->Plug(eax); 2511 context()->Plug(eax);
2518 } 2512 }
2519 } 2513 }
2520 2514
2521 2515
2522 void FullCodeGenerator::CallIC(Handle<Code> code, 2516 void FullCodeGenerator::CallIC(Handle<Code> code,
2523 TypeFeedbackId ast_id) { 2517 TypeFeedbackId ast_id) {
2524 ic_total_count_++; 2518 ic_total_count_++;
2525 __ call(code, RelocInfo::CODE_TARGET, ast_id); 2519 __ call(code, RelocInfo::CODE_TARGET, ast_id);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2560 // Code common for calls using the IC. 2554 // Code common for calls using the IC.
2561 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2555 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2562 Expression* key) { 2556 Expression* key) {
2563 // Load the key. 2557 // Load the key.
2564 VisitForAccumulatorValue(key); 2558 VisitForAccumulatorValue(key);
2565 2559
2566 Expression* callee = expr->expression(); 2560 Expression* callee = expr->expression();
2567 2561
2568 // Load the function from the receiver. 2562 // Load the function from the receiver.
2569 ASSERT(callee->IsProperty()); 2563 ASSERT(callee->IsProperty());
2570 __ mov(KeyedLoadIC::ReceiverRegister(), Operand(esp, 0)); 2564 __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0));
2571 // Move the key into the right register for the keyed load IC. 2565 __ mov(LoadIC::NameRegister(), eax);
2572 __ mov(KeyedLoadIC::NameRegister(), eax);
2573 EmitKeyedPropertyLoad(callee->AsProperty()); 2566 EmitKeyedPropertyLoad(callee->AsProperty());
2574 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2567 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2575 2568
2576 // Push the target function under the receiver. 2569 // Push the target function under the receiver.
2577 __ push(Operand(esp, 0)); 2570 __ push(Operand(esp, 0));
2578 __ mov(Operand(esp, kPointerSize), eax); 2571 __ mov(Operand(esp, kPointerSize), eax);
2579 2572
2580 EmitCall(expr, CallIC::METHOD); 2573 EmitCall(expr, CallIC::METHOD);
2581 } 2574 }
2582 2575
(...skipping 1618 matching lines...) Expand 10 before | Expand all | Expand 10 after
4201 if (assign_type == VARIABLE) { 4194 if (assign_type == VARIABLE) {
4202 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); 4195 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
4203 AccumulatorValueContext context(this); 4196 AccumulatorValueContext context(this);
4204 EmitVariableLoad(expr->expression()->AsVariableProxy()); 4197 EmitVariableLoad(expr->expression()->AsVariableProxy());
4205 } else { 4198 } else {
4206 // Reserve space for result of postfix operation. 4199 // Reserve space for result of postfix operation.
4207 if (expr->is_postfix() && !context()->IsEffect()) { 4200 if (expr->is_postfix() && !context()->IsEffect()) {
4208 __ push(Immediate(Smi::FromInt(0))); 4201 __ push(Immediate(Smi::FromInt(0)));
4209 } 4202 }
4210 if (assign_type == NAMED_PROPERTY) { 4203 if (assign_type == NAMED_PROPERTY) {
4211 // Put the object both on the stack and in edx. 4204 // Put the object both on the stack and in the register.
4212 VisitForAccumulatorValue(prop->obj()); 4205 VisitForStackValue(prop->obj());
4213 ASSERT(!eax.is(LoadIC::ReceiverRegister())); 4206 __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0));
4214 __ push(eax);
4215 __ mov(LoadIC::ReceiverRegister(), eax);
4216 EmitNamedPropertyLoad(prop); 4207 EmitNamedPropertyLoad(prop);
4217 } else { 4208 } else {
4218 VisitForStackValue(prop->obj()); 4209 VisitForStackValue(prop->obj());
4219 VisitForStackValue(prop->key()); 4210 VisitForStackValue(prop->key());
4220 __ mov(KeyedLoadIC::ReceiverRegister(), 4211 __ mov(LoadIC::ReceiverRegister(),
4221 Operand(esp, kPointerSize)); // Object. 4212 Operand(esp, kPointerSize)); // Object.
4222 __ mov(KeyedLoadIC::NameRegister(), Operand(esp, 0)); // Key. 4213 __ mov(LoadIC::NameRegister(), Operand(esp, 0)); // Key.
4223 EmitKeyedPropertyLoad(prop); 4214 EmitKeyedPropertyLoad(prop);
4224 } 4215 }
4225 } 4216 }
4226 4217
4227 // We need a second deoptimization point after loading the value 4218 // We need a second deoptimization point after loading the value
4228 // in case evaluating the property load my have a side effect. 4219 // in case evaluating the property load my have a side effect.
4229 if (assign_type == VARIABLE) { 4220 if (assign_type == VARIABLE) {
4230 PrepareForBailout(expr->expression(), TOS_REG); 4221 PrepareForBailout(expr->expression(), TOS_REG);
4231 } else { 4222 } else {
4232 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 4223 PrepareForBailoutForId(prop->LoadId(), TOS_REG);
(...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after
4804 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), 4795 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(),
4805 Assembler::target_address_at(call_target_address, 4796 Assembler::target_address_at(call_target_address,
4806 unoptimized_code)); 4797 unoptimized_code));
4807 return OSR_AFTER_STACK_CHECK; 4798 return OSR_AFTER_STACK_CHECK;
4808 } 4799 }
4809 4800
4810 4801
4811 } } // namespace v8::internal 4802 } } // namespace v8::internal
4812 4803
4813 #endif // V8_TARGET_ARCH_X87 4804 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « src/x87/debug-x87.cc ('k') | src/x87/ic-x87.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698