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

Side by Side Diff: src/x64/full-codegen-x64.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/x64/debug-x64.cc ('k') | src/x64/ic-x64.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_X64 7 #if V8_TARGET_ARCH_X64
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 1826 matching lines...) Expand 10 before | Expand all | Expand 10 after
1837 : KEYED_PROPERTY; 1837 : KEYED_PROPERTY;
1838 } 1838 }
1839 1839
1840 // Evaluate LHS expression. 1840 // Evaluate LHS expression.
1841 switch (assign_type) { 1841 switch (assign_type) {
1842 case VARIABLE: 1842 case VARIABLE:
1843 // Nothing to do here. 1843 // Nothing to do here.
1844 break; 1844 break;
1845 case NAMED_PROPERTY: 1845 case NAMED_PROPERTY:
1846 if (expr->is_compound()) { 1846 if (expr->is_compound()) {
1847 // We need the receiver both on the stack and in the accumulator. 1847 // We need the receiver both on the stack and in the register.
1848 VisitForAccumulatorValue(property->obj()); 1848 VisitForStackValue(property->obj());
1849 __ Push(result_register()); 1849 __ movp(LoadIC::ReceiverRegister(), Operand(rsp, 0));
1850 } else { 1850 } else {
1851 VisitForStackValue(property->obj()); 1851 VisitForStackValue(property->obj());
1852 } 1852 }
1853 break; 1853 break;
1854 case KEYED_PROPERTY: { 1854 case KEYED_PROPERTY: {
1855 if (expr->is_compound()) { 1855 if (expr->is_compound()) {
1856 VisitForStackValue(property->obj()); 1856 VisitForStackValue(property->obj());
1857 VisitForAccumulatorValue(property->key()); 1857 VisitForStackValue(property->key());
1858 __ movp(rdx, Operand(rsp, 0)); 1858 __ movp(LoadIC::ReceiverRegister(), Operand(rsp, kPointerSize));
1859 __ Push(rax); 1859 __ movp(LoadIC::NameRegister(), Operand(rsp, 0));
1860 } else { 1860 } else {
1861 VisitForStackValue(property->obj()); 1861 VisitForStackValue(property->obj());
1862 VisitForStackValue(property->key()); 1862 VisitForStackValue(property->key());
1863 } 1863 }
1864 break; 1864 break;
1865 } 1865 }
1866 } 1866 }
1867 1867
1868 // For compound assignments we need another deoptimization point after the 1868 // For compound assignments we need another deoptimization point after the
1869 // variable/property load. 1869 // variable/property load.
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1990 1990
1991 case Yield::DELEGATING: { 1991 case Yield::DELEGATING: {
1992 VisitForStackValue(expr->generator_object()); 1992 VisitForStackValue(expr->generator_object());
1993 1993
1994 // Initial stack layout is as follows: 1994 // Initial stack layout is as follows:
1995 // [sp + 1 * kPointerSize] iter 1995 // [sp + 1 * kPointerSize] iter
1996 // [sp + 0 * kPointerSize] g 1996 // [sp + 0 * kPointerSize] g
1997 1997
1998 Label l_catch, l_try, l_suspend, l_continuation, l_resume; 1998 Label l_catch, l_try, l_suspend, l_continuation, l_resume;
1999 Label l_next, l_call, l_loop; 1999 Label l_next, l_call, l_loop;
2000 Register load_receiver = LoadIC::ReceiverRegister();
2001 Register load_name = LoadIC::NameRegister();
2002
2000 // Initial send value is undefined. 2003 // Initial send value is undefined.
2001 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 2004 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
2002 __ jmp(&l_next); 2005 __ jmp(&l_next);
2003 2006
2004 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } 2007 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; }
2005 __ bind(&l_catch); 2008 __ bind(&l_catch);
2006 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); 2009 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
2007 __ LoadRoot(rcx, Heap::kthrow_stringRootIndex); // "throw" 2010 __ LoadRoot(load_name, Heap::kthrow_stringRootIndex); // "throw"
2008 __ Push(rcx); 2011 __ Push(load_name);
2009 __ Push(Operand(rsp, 2 * kPointerSize)); // iter 2012 __ Push(Operand(rsp, 2 * kPointerSize)); // iter
2010 __ Push(rax); // exception 2013 __ Push(rax); // exception
2011 __ jmp(&l_call); 2014 __ jmp(&l_call);
2012 2015
2013 // try { received = %yield result } 2016 // try { received = %yield result }
2014 // Shuffle the received result above a try handler and yield it without 2017 // Shuffle the received result above a try handler and yield it without
2015 // re-boxing. 2018 // re-boxing.
2016 __ bind(&l_try); 2019 __ bind(&l_try);
2017 __ Pop(rax); // result 2020 __ Pop(rax); // result
2018 __ PushTryHandler(StackHandler::CATCH, expr->index()); 2021 __ PushTryHandler(StackHandler::CATCH, expr->index());
2019 const int handler_size = StackHandlerConstants::kSize; 2022 const int handler_size = StackHandlerConstants::kSize;
2020 __ Push(rax); // result 2023 __ Push(rax); // result
(...skipping 14 matching lines...) Expand all
2035 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 2038 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
2036 __ movp(context_register(), 2039 __ movp(context_register(),
2037 Operand(rbp, StandardFrameConstants::kContextOffset)); 2040 Operand(rbp, StandardFrameConstants::kContextOffset));
2038 __ Pop(rax); // result 2041 __ Pop(rax); // result
2039 EmitReturnSequence(); 2042 EmitReturnSequence();
2040 __ bind(&l_resume); // received in rax 2043 __ bind(&l_resume); // received in rax
2041 __ PopTryHandler(); 2044 __ PopTryHandler();
2042 2045
2043 // receiver = iter; f = 'next'; arg = received; 2046 // receiver = iter; f = 'next'; arg = received;
2044 __ bind(&l_next); 2047 __ bind(&l_next);
2045 Register keyedload_receiver = KeyedLoadIC::ReceiverRegister();
2046 Register keyedload_name = KeyedLoadIC::NameRegister();
2047 ASSERT(keyedload_receiver.is(rdx));
2048 ASSERT(keyedload_name.is(rax));
2049 2048
2050 __ LoadRoot(rcx, Heap::knext_stringRootIndex); // "next" 2049 __ LoadRoot(load_name, Heap::knext_stringRootIndex);
2051 __ Push(rcx); 2050 __ Push(load_name); // "next"
2052 __ Push(Operand(rsp, 2 * kPointerSize)); // iter 2051 __ Push(Operand(rsp, 2 * kPointerSize)); // iter
2053 __ Push(rax); // received 2052 __ Push(rax); // received
2054 2053
2055 // result = receiver[f](arg); 2054 // result = receiver[f](arg);
2056 __ bind(&l_call); 2055 __ bind(&l_call);
2057 __ movp(keyedload_receiver, Operand(rsp, kPointerSize)); 2056 __ movp(load_receiver, Operand(rsp, kPointerSize));
2058 __ movp(keyedload_name, Operand(rsp, 2 * kPointerSize));
2059 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2057 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2060 CallIC(ic, TypeFeedbackId::None()); 2058 CallIC(ic, TypeFeedbackId::None());
2061 __ movp(rdi, rax); 2059 __ movp(rdi, rax);
2062 __ movp(Operand(rsp, 2 * kPointerSize), rdi); 2060 __ movp(Operand(rsp, 2 * kPointerSize), rdi);
2063 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); 2061 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD);
2064 __ CallStub(&stub); 2062 __ CallStub(&stub);
2065 2063
2066 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2064 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2067 __ Drop(1); // The function is still on the stack; drop it. 2065 __ Drop(1); // The function is still on the stack; drop it.
2068 2066
2069 // if (!result.done) goto l_try; 2067 // if (!result.done) goto l_try;
2070 __ bind(&l_loop); 2068 __ bind(&l_loop);
2071 Register load_receiver = LoadIC::ReceiverRegister(); 2069 __ Move(load_receiver, rax);
2072 Register load_name = LoadIC::NameRegister();
2073 ASSERT(load_receiver.is(rax));
2074 ASSERT(load_name.is(rcx));
2075
2076 __ Push(load_receiver); // save result 2070 __ Push(load_receiver); // save result
2077 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" 2071 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
2078 CallLoadIC(NOT_CONTEXTUAL); // rax=result.done 2072 CallLoadIC(NOT_CONTEXTUAL); // rax=result.done
2079 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); 2073 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
2080 CallIC(bool_ic); 2074 CallIC(bool_ic);
2081 __ testp(result_register(), result_register()); 2075 __ testp(result_register(), result_register());
2082 __ j(zero, &l_try); 2076 __ j(zero, &l_try);
2083 2077
2084 // result.value 2078 // result.value
2085 __ Pop(load_receiver); // result 2079 __ Pop(load_receiver); // result
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
2496 context()->Plug(rax); 2490 context()->Plug(rax);
2497 } 2491 }
2498 2492
2499 2493
2500 void FullCodeGenerator::VisitProperty(Property* expr) { 2494 void FullCodeGenerator::VisitProperty(Property* expr) {
2501 Comment cmnt(masm_, "[ Property"); 2495 Comment cmnt(masm_, "[ Property");
2502 Expression* key = expr->key(); 2496 Expression* key = expr->key();
2503 2497
2504 if (key->IsPropertyName()) { 2498 if (key->IsPropertyName()) {
2505 VisitForAccumulatorValue(expr->obj()); 2499 VisitForAccumulatorValue(expr->obj());
2506 ASSERT(rax.is(LoadIC::ReceiverRegister())); 2500 ASSERT(!rax.is(LoadIC::ReceiverRegister()));
2501 __ movp(LoadIC::ReceiverRegister(), rax);
2507 EmitNamedPropertyLoad(expr); 2502 EmitNamedPropertyLoad(expr);
2508 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2503 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
2509 context()->Plug(rax); 2504 context()->Plug(rax);
2510 } else { 2505 } else {
2511 VisitForStackValue(expr->obj()); 2506 VisitForStackValue(expr->obj());
2512 VisitForAccumulatorValue(expr->key()); 2507 VisitForAccumulatorValue(expr->key());
2513 ASSERT(rax.is(KeyedLoadIC::NameRegister())); 2508 __ Move(LoadIC::NameRegister(), rax);
2514 __ Pop(KeyedLoadIC::ReceiverRegister()); 2509 __ Pop(LoadIC::ReceiverRegister());
2515 EmitKeyedPropertyLoad(expr); 2510 EmitKeyedPropertyLoad(expr);
2516 context()->Plug(rax); 2511 context()->Plug(rax);
2517 } 2512 }
2518 } 2513 }
2519 2514
2520 2515
2521 void FullCodeGenerator::CallIC(Handle<Code> code, 2516 void FullCodeGenerator::CallIC(Handle<Code> code,
2522 TypeFeedbackId ast_id) { 2517 TypeFeedbackId ast_id) {
2523 ic_total_count_++; 2518 ic_total_count_++;
2524 __ call(code, RelocInfo::CODE_TARGET, ast_id); 2519 __ call(code, RelocInfo::CODE_TARGET, ast_id);
(...skipping 29 matching lines...) Expand all
2554 2549
2555 EmitCall(expr, call_type); 2550 EmitCall(expr, call_type);
2556 } 2551 }
2557 2552
2558 2553
2559 // Common code for calls using the IC. 2554 // Common code for calls using the IC.
2560 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2555 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2561 Expression* key) { 2556 Expression* key) {
2562 // Load the key. 2557 // Load the key.
2563 VisitForAccumulatorValue(key); 2558 VisitForAccumulatorValue(key);
2564 ASSERT(rax.is(KeyedLoadIC::NameRegister()));
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 __ movp(KeyedLoadIC::ReceiverRegister(), Operand(rsp, 0)); 2564 __ movp(LoadIC::ReceiverRegister(), Operand(rsp, 0));
2565 __ Move(LoadIC::NameRegister(), rax);
2571 EmitKeyedPropertyLoad(callee->AsProperty()); 2566 EmitKeyedPropertyLoad(callee->AsProperty());
2572 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2567 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2573 2568
2574 // Push the target function under the receiver. 2569 // Push the target function under the receiver.
2575 __ Push(Operand(rsp, 0)); 2570 __ Push(Operand(rsp, 0));
2576 __ movp(Operand(rsp, kPointerSize), rax); 2571 __ movp(Operand(rsp, kPointerSize), rax);
2577 2572
2578 EmitCall(expr, CallIC::METHOD); 2573 EmitCall(expr, CallIC::METHOD);
2579 } 2574 }
2580 2575
(...skipping 1636 matching lines...) Expand 10 before | Expand all | Expand 10 after
4217 if (assign_type == VARIABLE) { 4212 if (assign_type == VARIABLE) {
4218 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); 4213 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
4219 AccumulatorValueContext context(this); 4214 AccumulatorValueContext context(this);
4220 EmitVariableLoad(expr->expression()->AsVariableProxy()); 4215 EmitVariableLoad(expr->expression()->AsVariableProxy());
4221 } else { 4216 } else {
4222 // Reserve space for result of postfix operation. 4217 // Reserve space for result of postfix operation.
4223 if (expr->is_postfix() && !context()->IsEffect()) { 4218 if (expr->is_postfix() && !context()->IsEffect()) {
4224 __ Push(Smi::FromInt(0)); 4219 __ Push(Smi::FromInt(0));
4225 } 4220 }
4226 if (assign_type == NAMED_PROPERTY) { 4221 if (assign_type == NAMED_PROPERTY) {
4227 VisitForAccumulatorValue(prop->obj()); 4222 VisitForStackValue(prop->obj());
4228 ASSERT(rax.is(LoadIC::ReceiverRegister())); 4223 __ movp(LoadIC::ReceiverRegister(), Operand(rsp, 0));
4229 __ Push(rax); // Copy of receiver, needed for later store.
4230 EmitNamedPropertyLoad(prop); 4224 EmitNamedPropertyLoad(prop);
4231 } else { 4225 } else {
4232 VisitForStackValue(prop->obj()); 4226 VisitForStackValue(prop->obj());
4233 VisitForAccumulatorValue(prop->key()); 4227 VisitForStackValue(prop->key());
4234 ASSERT(rax.is(KeyedLoadIC::NameRegister()));
4235 // Leave receiver on stack 4228 // Leave receiver on stack
4236 __ movp(KeyedLoadIC::ReceiverRegister(), Operand(rsp, 0)); 4229 __ movp(LoadIC::ReceiverRegister(), Operand(rsp, kPointerSize));
4237 // Copy of key, needed for later store. 4230 // Copy of key, needed for later store.
4238 __ Push(KeyedLoadIC::NameRegister()); 4231 __ movp(LoadIC::NameRegister(), Operand(rsp, 0));
4239 EmitKeyedPropertyLoad(prop); 4232 EmitKeyedPropertyLoad(prop);
4240 } 4233 }
4241 } 4234 }
4242 4235
4243 // We need a second deoptimization point after loading the value 4236 // We need a second deoptimization point after loading the value
4244 // in case evaluating the property load my have a side effect. 4237 // in case evaluating the property load my have a side effect.
4245 if (assign_type == VARIABLE) { 4238 if (assign_type == VARIABLE) {
4246 PrepareForBailout(expr->expression(), TOS_REG); 4239 PrepareForBailout(expr->expression(), TOS_REG);
4247 } else { 4240 } else {
4248 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 4241 PrepareForBailoutForId(prop->LoadId(), TOS_REG);
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after
4819 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), 4812 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(),
4820 Assembler::target_address_at(call_target_address, 4813 Assembler::target_address_at(call_target_address,
4821 unoptimized_code)); 4814 unoptimized_code));
4822 return OSR_AFTER_STACK_CHECK; 4815 return OSR_AFTER_STACK_CHECK;
4823 } 4816 }
4824 4817
4825 4818
4826 } } // namespace v8::internal 4819 } } // namespace v8::internal
4827 4820
4828 #endif // V8_TARGET_ARCH_X64 4821 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/debug-x64.cc ('k') | src/x64/ic-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698