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

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

Issue 527093002: Make concrete classes for individual call descriptors. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE. Created 6 years, 3 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_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 1344 matching lines...) Expand 10 before | Expand all | Expand 10 after
1355 __ cmpp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0)); 1355 __ cmpp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0));
1356 __ j(not_equal, slow); 1356 __ j(not_equal, slow);
1357 // Load next context in chain. 1357 // Load next context in chain.
1358 __ movp(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); 1358 __ movp(temp, ContextOperand(temp, Context::PREVIOUS_INDEX));
1359 __ jmp(&next); 1359 __ jmp(&next);
1360 __ bind(&fast); 1360 __ bind(&fast);
1361 } 1361 }
1362 1362
1363 // All extension objects were empty and it is safe to use a global 1363 // All extension objects were empty and it is safe to use a global
1364 // load IC call. 1364 // load IC call.
1365 __ movp(LoadConvention::ReceiverRegister(), GlobalObjectOperand()); 1365 __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
1366 __ Move(LoadConvention::NameRegister(), proxy->var()->name()); 1366 __ Move(LoadDescriptor::NameRegister(), proxy->var()->name());
1367 if (FLAG_vector_ics) { 1367 if (FLAG_vector_ics) {
1368 __ Move(VectorLoadConvention::SlotRegister(), 1368 __ Move(VectorLoadICDescriptor::SlotRegister(),
1369 Smi::FromInt(proxy->VariableFeedbackSlot())); 1369 Smi::FromInt(proxy->VariableFeedbackSlot()));
1370 } 1370 }
1371 1371
1372 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) 1372 ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
1373 ? NOT_CONTEXTUAL 1373 ? NOT_CONTEXTUAL
1374 : CONTEXTUAL; 1374 : CONTEXTUAL;
1375 CallLoadIC(mode); 1375 CallLoadIC(mode);
1376 } 1376 }
1377 1377
1378 1378
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1441 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { 1441 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
1442 // Record position before possible IC call. 1442 // Record position before possible IC call.
1443 SetSourcePosition(proxy->position()); 1443 SetSourcePosition(proxy->position());
1444 Variable* var = proxy->var(); 1444 Variable* var = proxy->var();
1445 1445
1446 // Three cases: global variables, lookup variables, and all other types of 1446 // Three cases: global variables, lookup variables, and all other types of
1447 // variables. 1447 // variables.
1448 switch (var->location()) { 1448 switch (var->location()) {
1449 case Variable::UNALLOCATED: { 1449 case Variable::UNALLOCATED: {
1450 Comment cmnt(masm_, "[ Global variable"); 1450 Comment cmnt(masm_, "[ Global variable");
1451 __ Move(LoadConvention::NameRegister(), var->name()); 1451 __ Move(LoadDescriptor::NameRegister(), var->name());
1452 __ movp(LoadConvention::ReceiverRegister(), GlobalObjectOperand()); 1452 __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
1453 if (FLAG_vector_ics) { 1453 if (FLAG_vector_ics) {
1454 __ Move(VectorLoadConvention::SlotRegister(), 1454 __ Move(VectorLoadICDescriptor::SlotRegister(),
1455 Smi::FromInt(proxy->VariableFeedbackSlot())); 1455 Smi::FromInt(proxy->VariableFeedbackSlot()));
1456 } 1456 }
1457 CallLoadIC(CONTEXTUAL); 1457 CallLoadIC(CONTEXTUAL);
1458 context()->Plug(rax); 1458 context()->Plug(rax);
1459 break; 1459 break;
1460 } 1460 }
1461 1461
1462 case Variable::PARAMETER: 1462 case Variable::PARAMETER:
1463 case Variable::LOCAL: 1463 case Variable::LOCAL:
1464 case Variable::CONTEXT: { 1464 case Variable::CONTEXT: {
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1659 switch (property->kind()) { 1659 switch (property->kind()) {
1660 case ObjectLiteral::Property::CONSTANT: 1660 case ObjectLiteral::Property::CONSTANT:
1661 UNREACHABLE(); 1661 UNREACHABLE();
1662 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1662 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1663 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); 1663 DCHECK(!CompileTimeValue::IsCompileTimeValue(value));
1664 // Fall through. 1664 // Fall through.
1665 case ObjectLiteral::Property::COMPUTED: 1665 case ObjectLiteral::Property::COMPUTED:
1666 if (key->value()->IsInternalizedString()) { 1666 if (key->value()->IsInternalizedString()) {
1667 if (property->emit_store()) { 1667 if (property->emit_store()) {
1668 VisitForAccumulatorValue(value); 1668 VisitForAccumulatorValue(value);
1669 DCHECK(StoreConvention::ValueRegister().is(rax)); 1669 DCHECK(StoreDescriptor::ValueRegister().is(rax));
1670 __ Move(StoreConvention::NameRegister(), key->value()); 1670 __ Move(StoreDescriptor::NameRegister(), key->value());
1671 __ movp(StoreConvention::ReceiverRegister(), Operand(rsp, 0)); 1671 __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0));
1672 CallStoreIC(key->LiteralFeedbackId()); 1672 CallStoreIC(key->LiteralFeedbackId());
1673 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1673 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1674 } else { 1674 } else {
1675 VisitForEffect(value); 1675 VisitForEffect(value);
1676 } 1676 }
1677 break; 1677 break;
1678 } 1678 }
1679 __ Push(Operand(rsp, 0)); // Duplicate receiver. 1679 __ Push(Operand(rsp, 0)); // Duplicate receiver.
1680 VisitForStackValue(key); 1680 VisitForStackValue(key);
1681 VisitForStackValue(value); 1681 VisitForStackValue(value);
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1840 1840
1841 // Evaluate LHS expression. 1841 // Evaluate LHS expression.
1842 switch (assign_type) { 1842 switch (assign_type) {
1843 case VARIABLE: 1843 case VARIABLE:
1844 // Nothing to do here. 1844 // Nothing to do here.
1845 break; 1845 break;
1846 case NAMED_PROPERTY: 1846 case NAMED_PROPERTY:
1847 if (expr->is_compound()) { 1847 if (expr->is_compound()) {
1848 // We need the receiver both on the stack and in the register. 1848 // We need the receiver both on the stack and in the register.
1849 VisitForStackValue(property->obj()); 1849 VisitForStackValue(property->obj());
1850 __ movp(LoadConvention::ReceiverRegister(), Operand(rsp, 0)); 1850 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0));
1851 } else { 1851 } else {
1852 VisitForStackValue(property->obj()); 1852 VisitForStackValue(property->obj());
1853 } 1853 }
1854 break; 1854 break;
1855 case KEYED_PROPERTY: { 1855 case KEYED_PROPERTY: {
1856 if (expr->is_compound()) { 1856 if (expr->is_compound()) {
1857 VisitForStackValue(property->obj()); 1857 VisitForStackValue(property->obj());
1858 VisitForStackValue(property->key()); 1858 VisitForStackValue(property->key());
1859 __ movp(LoadConvention::ReceiverRegister(), Operand(rsp, kPointerSize)); 1859 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, kPointerSize));
1860 __ movp(LoadConvention::NameRegister(), Operand(rsp, 0)); 1860 __ movp(LoadDescriptor::NameRegister(), Operand(rsp, 0));
1861 } else { 1861 } else {
1862 VisitForStackValue(property->obj()); 1862 VisitForStackValue(property->obj());
1863 VisitForStackValue(property->key()); 1863 VisitForStackValue(property->key());
1864 } 1864 }
1865 break; 1865 break;
1866 } 1866 }
1867 } 1867 }
1868 1868
1869 // For compound assignments we need another deoptimization point after the 1869 // For compound assignments we need another deoptimization point after the
1870 // variable/property load. 1870 // variable/property load.
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1991 1991
1992 case Yield::kDelegating: { 1992 case Yield::kDelegating: {
1993 VisitForStackValue(expr->generator_object()); 1993 VisitForStackValue(expr->generator_object());
1994 1994
1995 // Initial stack layout is as follows: 1995 // Initial stack layout is as follows:
1996 // [sp + 1 * kPointerSize] iter 1996 // [sp + 1 * kPointerSize] iter
1997 // [sp + 0 * kPointerSize] g 1997 // [sp + 0 * kPointerSize] g
1998 1998
1999 Label l_catch, l_try, l_suspend, l_continuation, l_resume; 1999 Label l_catch, l_try, l_suspend, l_continuation, l_resume;
2000 Label l_next, l_call, l_loop; 2000 Label l_next, l_call, l_loop;
2001 Register load_receiver = LoadConvention::ReceiverRegister(); 2001 Register load_receiver = LoadDescriptor::ReceiverRegister();
2002 Register load_name = LoadConvention::NameRegister(); 2002 Register load_name = LoadDescriptor::NameRegister();
2003 2003
2004 // Initial send value is undefined. 2004 // Initial send value is undefined.
2005 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 2005 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
2006 __ jmp(&l_next); 2006 __ jmp(&l_next);
2007 2007
2008 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } 2008 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; }
2009 __ bind(&l_catch); 2009 __ bind(&l_catch);
2010 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); 2010 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
2011 __ LoadRoot(load_name, Heap::kthrow_stringRootIndex); // "throw" 2011 __ LoadRoot(load_name, Heap::kthrow_stringRootIndex); // "throw"
2012 __ Push(load_name); 2012 __ Push(load_name);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2049 2049
2050 __ LoadRoot(load_name, Heap::knext_stringRootIndex); 2050 __ LoadRoot(load_name, Heap::knext_stringRootIndex);
2051 __ Push(load_name); // "next" 2051 __ Push(load_name); // "next"
2052 __ Push(Operand(rsp, 2 * kPointerSize)); // iter 2052 __ Push(Operand(rsp, 2 * kPointerSize)); // iter
2053 __ Push(rax); // received 2053 __ Push(rax); // received
2054 2054
2055 // result = receiver[f](arg); 2055 // result = receiver[f](arg);
2056 __ bind(&l_call); 2056 __ bind(&l_call);
2057 __ movp(load_receiver, Operand(rsp, kPointerSize)); 2057 __ movp(load_receiver, Operand(rsp, kPointerSize));
2058 if (FLAG_vector_ics) { 2058 if (FLAG_vector_ics) {
2059 __ Move(VectorLoadConvention::SlotRegister(), 2059 __ Move(VectorLoadICDescriptor::SlotRegister(),
2060 Smi::FromInt(expr->KeyedLoadFeedbackSlot())); 2060 Smi::FromInt(expr->KeyedLoadFeedbackSlot()));
2061 } 2061 }
2062 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2062 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2063 CallIC(ic, TypeFeedbackId::None()); 2063 CallIC(ic, TypeFeedbackId::None());
2064 __ movp(rdi, rax); 2064 __ movp(rdi, rax);
2065 __ movp(Operand(rsp, 2 * kPointerSize), rdi); 2065 __ movp(Operand(rsp, 2 * kPointerSize), rdi);
2066 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); 2066 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD);
2067 __ CallStub(&stub); 2067 __ CallStub(&stub);
2068 2068
2069 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2069 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2070 __ Drop(1); // The function is still on the stack; drop it. 2070 __ Drop(1); // The function is still on the stack; drop it.
2071 2071
2072 // if (!result.done) goto l_try; 2072 // if (!result.done) goto l_try;
2073 __ bind(&l_loop); 2073 __ bind(&l_loop);
2074 __ Move(load_receiver, rax); 2074 __ Move(load_receiver, rax);
2075 __ Push(load_receiver); // save result 2075 __ Push(load_receiver); // save result
2076 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" 2076 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
2077 if (FLAG_vector_ics) { 2077 if (FLAG_vector_ics) {
2078 __ Move(VectorLoadConvention::SlotRegister(), 2078 __ Move(VectorLoadICDescriptor::SlotRegister(),
2079 Smi::FromInt(expr->DoneFeedbackSlot())); 2079 Smi::FromInt(expr->DoneFeedbackSlot()));
2080 } 2080 }
2081 CallLoadIC(NOT_CONTEXTUAL); // rax=result.done 2081 CallLoadIC(NOT_CONTEXTUAL); // rax=result.done
2082 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); 2082 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
2083 CallIC(bool_ic); 2083 CallIC(bool_ic);
2084 __ testp(result_register(), result_register()); 2084 __ testp(result_register(), result_register());
2085 __ j(zero, &l_try); 2085 __ j(zero, &l_try);
2086 2086
2087 // result.value 2087 // result.value
2088 __ Pop(load_receiver); // result 2088 __ Pop(load_receiver); // result
2089 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" 2089 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
2090 if (FLAG_vector_ics) { 2090 if (FLAG_vector_ics) {
2091 __ Move(VectorLoadConvention::SlotRegister(), 2091 __ Move(VectorLoadICDescriptor::SlotRegister(),
2092 Smi::FromInt(expr->ValueFeedbackSlot())); 2092 Smi::FromInt(expr->ValueFeedbackSlot()));
2093 } 2093 }
2094 CallLoadIC(NOT_CONTEXTUAL); // result.value in rax 2094 CallLoadIC(NOT_CONTEXTUAL); // result.value in rax
2095 context()->DropAndPlug(2, rax); // drop iter and g 2095 context()->DropAndPlug(2, rax); // drop iter and g
2096 break; 2096 break;
2097 } 2097 }
2098 } 2098 }
2099 } 2099 }
2100 2100
2101 2101
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
2244 // Only the value field needs a write barrier, as the other values are in the 2244 // Only the value field needs a write barrier, as the other values are in the
2245 // root set. 2245 // root set.
2246 __ RecordWriteField(rax, JSGeneratorObject::kResultValuePropertyOffset, 2246 __ RecordWriteField(rax, JSGeneratorObject::kResultValuePropertyOffset,
2247 rcx, rdx, kDontSaveFPRegs); 2247 rcx, rdx, kDontSaveFPRegs);
2248 } 2248 }
2249 2249
2250 2250
2251 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 2251 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
2252 SetSourcePosition(prop->position()); 2252 SetSourcePosition(prop->position());
2253 Literal* key = prop->key()->AsLiteral(); 2253 Literal* key = prop->key()->AsLiteral();
2254 __ Move(LoadConvention::NameRegister(), key->value()); 2254 __ Move(LoadDescriptor::NameRegister(), key->value());
2255 if (FLAG_vector_ics) { 2255 if (FLAG_vector_ics) {
2256 __ Move(VectorLoadConvention::SlotRegister(), 2256 __ Move(VectorLoadICDescriptor::SlotRegister(),
2257 Smi::FromInt(prop->PropertyFeedbackSlot())); 2257 Smi::FromInt(prop->PropertyFeedbackSlot()));
2258 CallLoadIC(NOT_CONTEXTUAL); 2258 CallLoadIC(NOT_CONTEXTUAL);
2259 } else { 2259 } else {
2260 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); 2260 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
2261 } 2261 }
2262 } 2262 }
2263 2263
2264 2264
2265 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 2265 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2266 SetSourcePosition(prop->position()); 2266 SetSourcePosition(prop->position());
2267 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2267 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2268 if (FLAG_vector_ics) { 2268 if (FLAG_vector_ics) {
2269 __ Move(VectorLoadConvention::SlotRegister(), 2269 __ Move(VectorLoadICDescriptor::SlotRegister(),
2270 Smi::FromInt(prop->PropertyFeedbackSlot())); 2270 Smi::FromInt(prop->PropertyFeedbackSlot()));
2271 CallIC(ic); 2271 CallIC(ic);
2272 } else { 2272 } else {
2273 CallIC(ic, prop->PropertyFeedbackId()); 2273 CallIC(ic, prop->PropertyFeedbackId());
2274 } 2274 }
2275 } 2275 }
2276 2276
2277 2277
2278 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2278 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
2279 Token::Value op, 2279 Token::Value op,
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
2365 switch (assign_type) { 2365 switch (assign_type) {
2366 case VARIABLE: { 2366 case VARIABLE: {
2367 Variable* var = expr->AsVariableProxy()->var(); 2367 Variable* var = expr->AsVariableProxy()->var();
2368 EffectContext context(this); 2368 EffectContext context(this);
2369 EmitVariableAssignment(var, Token::ASSIGN); 2369 EmitVariableAssignment(var, Token::ASSIGN);
2370 break; 2370 break;
2371 } 2371 }
2372 case NAMED_PROPERTY: { 2372 case NAMED_PROPERTY: {
2373 __ Push(rax); // Preserve value. 2373 __ Push(rax); // Preserve value.
2374 VisitForAccumulatorValue(prop->obj()); 2374 VisitForAccumulatorValue(prop->obj());
2375 __ Move(StoreConvention::ReceiverRegister(), rax); 2375 __ Move(StoreDescriptor::ReceiverRegister(), rax);
2376 __ Pop(StoreConvention::ValueRegister()); // Restore value. 2376 __ Pop(StoreDescriptor::ValueRegister()); // Restore value.
2377 __ Move(StoreConvention::NameRegister(), 2377 __ Move(StoreDescriptor::NameRegister(),
2378 prop->key()->AsLiteral()->value()); 2378 prop->key()->AsLiteral()->value());
2379 CallStoreIC(); 2379 CallStoreIC();
2380 break; 2380 break;
2381 } 2381 }
2382 case KEYED_PROPERTY: { 2382 case KEYED_PROPERTY: {
2383 __ Push(rax); // Preserve value. 2383 __ Push(rax); // Preserve value.
2384 VisitForStackValue(prop->obj()); 2384 VisitForStackValue(prop->obj());
2385 VisitForAccumulatorValue(prop->key()); 2385 VisitForAccumulatorValue(prop->key());
2386 __ Move(StoreConvention::NameRegister(), rax); 2386 __ Move(StoreDescriptor::NameRegister(), rax);
2387 __ Pop(StoreConvention::ReceiverRegister()); 2387 __ Pop(StoreDescriptor::ReceiverRegister());
2388 __ Pop(StoreConvention::ValueRegister()); // Restore value. 2388 __ Pop(StoreDescriptor::ValueRegister()); // Restore value.
2389 Handle<Code> ic = strict_mode() == SLOPPY 2389 Handle<Code> ic = strict_mode() == SLOPPY
2390 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2390 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2391 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2391 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2392 CallIC(ic); 2392 CallIC(ic);
2393 break; 2393 break;
2394 } 2394 }
2395 } 2395 }
2396 context()->Plug(rax); 2396 context()->Plug(rax);
2397 } 2397 }
2398 2398
2399 2399
2400 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( 2400 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
2401 Variable* var, MemOperand location) { 2401 Variable* var, MemOperand location) {
2402 __ movp(location, rax); 2402 __ movp(location, rax);
2403 if (var->IsContextSlot()) { 2403 if (var->IsContextSlot()) {
2404 __ movp(rdx, rax); 2404 __ movp(rdx, rax);
2405 __ RecordWriteContextSlot( 2405 __ RecordWriteContextSlot(
2406 rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs); 2406 rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs);
2407 } 2407 }
2408 } 2408 }
2409 2409
2410 2410
2411 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 2411 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
2412 Token::Value op) { 2412 Token::Value op) {
2413 if (var->IsUnallocated()) { 2413 if (var->IsUnallocated()) {
2414 // Global var, const, or let. 2414 // Global var, const, or let.
2415 __ Move(StoreConvention::NameRegister(), var->name()); 2415 __ Move(StoreDescriptor::NameRegister(), var->name());
2416 __ movp(StoreConvention::ReceiverRegister(), GlobalObjectOperand()); 2416 __ movp(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand());
2417 CallStoreIC(); 2417 CallStoreIC();
2418 2418
2419 } else if (op == Token::INIT_CONST_LEGACY) { 2419 } else if (op == Token::INIT_CONST_LEGACY) {
2420 // Const initializers need a write barrier. 2420 // Const initializers need a write barrier.
2421 DCHECK(!var->IsParameter()); // No const parameters. 2421 DCHECK(!var->IsParameter()); // No const parameters.
2422 if (var->IsLookupSlot()) { 2422 if (var->IsLookupSlot()) {
2423 __ Push(rax); 2423 __ Push(rax);
2424 __ Push(rsi); 2424 __ Push(rsi);
2425 __ Push(var->name()); 2425 __ Push(var->name());
2426 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); 2426 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2476 2476
2477 2477
2478 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2478 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2479 // Assignment to a property, using a named store IC. 2479 // Assignment to a property, using a named store IC.
2480 Property* prop = expr->target()->AsProperty(); 2480 Property* prop = expr->target()->AsProperty();
2481 DCHECK(prop != NULL); 2481 DCHECK(prop != NULL);
2482 DCHECK(prop->key()->IsLiteral()); 2482 DCHECK(prop->key()->IsLiteral());
2483 2483
2484 // Record source code position before IC call. 2484 // Record source code position before IC call.
2485 SetSourcePosition(expr->position()); 2485 SetSourcePosition(expr->position());
2486 __ Move(StoreConvention::NameRegister(), prop->key()->AsLiteral()->value()); 2486 __ Move(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value());
2487 __ Pop(StoreConvention::ReceiverRegister()); 2487 __ Pop(StoreDescriptor::ReceiverRegister());
2488 CallStoreIC(expr->AssignmentFeedbackId()); 2488 CallStoreIC(expr->AssignmentFeedbackId());
2489 2489
2490 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2490 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2491 context()->Plug(rax); 2491 context()->Plug(rax);
2492 } 2492 }
2493 2493
2494 2494
2495 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2495 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2496 // Assignment to a property, using a keyed store IC. 2496 // Assignment to a property, using a keyed store IC.
2497 2497
2498 __ Pop(StoreConvention::NameRegister()); // Key. 2498 __ Pop(StoreDescriptor::NameRegister()); // Key.
2499 __ Pop(StoreConvention::ReceiverRegister()); 2499 __ Pop(StoreDescriptor::ReceiverRegister());
2500 DCHECK(StoreConvention::ValueRegister().is(rax)); 2500 DCHECK(StoreDescriptor::ValueRegister().is(rax));
2501 // Record source code position before IC call. 2501 // Record source code position before IC call.
2502 SetSourcePosition(expr->position()); 2502 SetSourcePosition(expr->position());
2503 Handle<Code> ic = strict_mode() == SLOPPY 2503 Handle<Code> ic = strict_mode() == SLOPPY
2504 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2504 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2505 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2505 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2506 CallIC(ic, expr->AssignmentFeedbackId()); 2506 CallIC(ic, expr->AssignmentFeedbackId());
2507 2507
2508 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2508 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2509 context()->Plug(rax); 2509 context()->Plug(rax);
2510 } 2510 }
2511 2511
2512 2512
2513 void FullCodeGenerator::VisitProperty(Property* expr) { 2513 void FullCodeGenerator::VisitProperty(Property* expr) {
2514 Comment cmnt(masm_, "[ Property"); 2514 Comment cmnt(masm_, "[ Property");
2515 Expression* key = expr->key(); 2515 Expression* key = expr->key();
2516 2516
2517 if (key->IsPropertyName()) { 2517 if (key->IsPropertyName()) {
2518 VisitForAccumulatorValue(expr->obj()); 2518 VisitForAccumulatorValue(expr->obj());
2519 DCHECK(!rax.is(LoadConvention::ReceiverRegister())); 2519 DCHECK(!rax.is(LoadDescriptor::ReceiverRegister()));
2520 __ movp(LoadConvention::ReceiverRegister(), rax); 2520 __ movp(LoadDescriptor::ReceiverRegister(), rax);
2521 EmitNamedPropertyLoad(expr); 2521 EmitNamedPropertyLoad(expr);
2522 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2522 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
2523 context()->Plug(rax); 2523 context()->Plug(rax);
2524 } else { 2524 } else {
2525 VisitForStackValue(expr->obj()); 2525 VisitForStackValue(expr->obj());
2526 VisitForAccumulatorValue(expr->key()); 2526 VisitForAccumulatorValue(expr->key());
2527 __ Move(LoadConvention::NameRegister(), rax); 2527 __ Move(LoadDescriptor::NameRegister(), rax);
2528 __ Pop(LoadConvention::ReceiverRegister()); 2528 __ Pop(LoadDescriptor::ReceiverRegister());
2529 EmitKeyedPropertyLoad(expr); 2529 EmitKeyedPropertyLoad(expr);
2530 context()->Plug(rax); 2530 context()->Plug(rax);
2531 } 2531 }
2532 } 2532 }
2533 2533
2534 2534
2535 void FullCodeGenerator::CallIC(Handle<Code> code, 2535 void FullCodeGenerator::CallIC(Handle<Code> code,
2536 TypeFeedbackId ast_id) { 2536 TypeFeedbackId ast_id) {
2537 ic_total_count_++; 2537 ic_total_count_++;
2538 __ call(code, RelocInfo::CODE_TARGET, ast_id); 2538 __ call(code, RelocInfo::CODE_TARGET, ast_id);
(...skipping 12 matching lines...) Expand all
2551 { StackValueContext context(this); 2551 { StackValueContext context(this);
2552 EmitVariableLoad(callee->AsVariableProxy()); 2552 EmitVariableLoad(callee->AsVariableProxy());
2553 PrepareForBailout(callee, NO_REGISTERS); 2553 PrepareForBailout(callee, NO_REGISTERS);
2554 } 2554 }
2555 // Push undefined as receiver. This is patched in the method prologue if it 2555 // Push undefined as receiver. This is patched in the method prologue if it
2556 // is a sloppy mode method. 2556 // is a sloppy mode method.
2557 __ Push(isolate()->factory()->undefined_value()); 2557 __ Push(isolate()->factory()->undefined_value());
2558 } else { 2558 } else {
2559 // Load the function from the receiver. 2559 // Load the function from the receiver.
2560 DCHECK(callee->IsProperty()); 2560 DCHECK(callee->IsProperty());
2561 __ movp(LoadConvention::ReceiverRegister(), Operand(rsp, 0)); 2561 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0));
2562 EmitNamedPropertyLoad(callee->AsProperty()); 2562 EmitNamedPropertyLoad(callee->AsProperty());
2563 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2563 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2564 // Push the target function under the receiver. 2564 // Push the target function under the receiver.
2565 __ Push(Operand(rsp, 0)); 2565 __ Push(Operand(rsp, 0));
2566 __ movp(Operand(rsp, kPointerSize), rax); 2566 __ movp(Operand(rsp, kPointerSize), rax);
2567 } 2567 }
2568 2568
2569 EmitCall(expr, call_type); 2569 EmitCall(expr, call_type);
2570 } 2570 }
2571 2571
2572 2572
2573 // Common code for calls using the IC. 2573 // Common code for calls using the IC.
2574 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2574 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2575 Expression* key) { 2575 Expression* key) {
2576 // Load the key. 2576 // Load the key.
2577 VisitForAccumulatorValue(key); 2577 VisitForAccumulatorValue(key);
2578 2578
2579 Expression* callee = expr->expression(); 2579 Expression* callee = expr->expression();
2580 2580
2581 // Load the function from the receiver. 2581 // Load the function from the receiver.
2582 DCHECK(callee->IsProperty()); 2582 DCHECK(callee->IsProperty());
2583 __ movp(LoadConvention::ReceiverRegister(), Operand(rsp, 0)); 2583 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0));
2584 __ Move(LoadConvention::NameRegister(), rax); 2584 __ Move(LoadDescriptor::NameRegister(), rax);
2585 EmitKeyedPropertyLoad(callee->AsProperty()); 2585 EmitKeyedPropertyLoad(callee->AsProperty());
2586 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2586 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2587 2587
2588 // Push the target function under the receiver. 2588 // Push the target function under the receiver.
2589 __ Push(Operand(rsp, 0)); 2589 __ Push(Operand(rsp, 0));
2590 __ movp(Operand(rsp, kPointerSize), rax); 2590 __ movp(Operand(rsp, kPointerSize), rax);
2591 2591
2592 EmitCall(expr, CallIC::METHOD); 2592 EmitCall(expr, CallIC::METHOD);
2593 } 2593 }
2594 2594
(...skipping 1457 matching lines...) Expand 10 before | Expand all | Expand 10 after
4052 Comment cmnt(masm_, "[ CallRuntime"); 4052 Comment cmnt(masm_, "[ CallRuntime");
4053 ZoneList<Expression*>* args = expr->arguments(); 4053 ZoneList<Expression*>* args = expr->arguments();
4054 int arg_count = args->length(); 4054 int arg_count = args->length();
4055 4055
4056 if (expr->is_jsruntime()) { 4056 if (expr->is_jsruntime()) {
4057 // Push the builtins object as receiver. 4057 // Push the builtins object as receiver.
4058 __ movp(rax, GlobalObjectOperand()); 4058 __ movp(rax, GlobalObjectOperand());
4059 __ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); 4059 __ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset));
4060 4060
4061 // Load the function from the receiver. 4061 // Load the function from the receiver.
4062 __ movp(LoadConvention::ReceiverRegister(), Operand(rsp, 0)); 4062 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0));
4063 __ Move(LoadConvention::NameRegister(), expr->name()); 4063 __ Move(LoadDescriptor::NameRegister(), expr->name());
4064 if (FLAG_vector_ics) { 4064 if (FLAG_vector_ics) {
4065 __ Move(VectorLoadConvention::SlotRegister(), 4065 __ Move(VectorLoadICDescriptor::SlotRegister(),
4066 Smi::FromInt(expr->CallRuntimeFeedbackSlot())); 4066 Smi::FromInt(expr->CallRuntimeFeedbackSlot()));
4067 CallLoadIC(NOT_CONTEXTUAL); 4067 CallLoadIC(NOT_CONTEXTUAL);
4068 } else { 4068 } else {
4069 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); 4069 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
4070 } 4070 }
4071 4071
4072 // Push the target function under the receiver. 4072 // Push the target function under the receiver.
4073 __ Push(Operand(rsp, 0)); 4073 __ Push(Operand(rsp, 0));
4074 __ movp(Operand(rsp, kPointerSize), rax); 4074 __ movp(Operand(rsp, kPointerSize), rax);
4075 4075
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
4238 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); 4238 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL);
4239 AccumulatorValueContext context(this); 4239 AccumulatorValueContext context(this);
4240 EmitVariableLoad(expr->expression()->AsVariableProxy()); 4240 EmitVariableLoad(expr->expression()->AsVariableProxy());
4241 } else { 4241 } else {
4242 // Reserve space for result of postfix operation. 4242 // Reserve space for result of postfix operation.
4243 if (expr->is_postfix() && !context()->IsEffect()) { 4243 if (expr->is_postfix() && !context()->IsEffect()) {
4244 __ Push(Smi::FromInt(0)); 4244 __ Push(Smi::FromInt(0));
4245 } 4245 }
4246 if (assign_type == NAMED_PROPERTY) { 4246 if (assign_type == NAMED_PROPERTY) {
4247 VisitForStackValue(prop->obj()); 4247 VisitForStackValue(prop->obj());
4248 __ movp(LoadConvention::ReceiverRegister(), Operand(rsp, 0)); 4248 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0));
4249 EmitNamedPropertyLoad(prop); 4249 EmitNamedPropertyLoad(prop);
4250 } else { 4250 } else {
4251 VisitForStackValue(prop->obj()); 4251 VisitForStackValue(prop->obj());
4252 VisitForStackValue(prop->key()); 4252 VisitForStackValue(prop->key());
4253 // Leave receiver on stack 4253 // Leave receiver on stack
4254 __ movp(LoadConvention::ReceiverRegister(), Operand(rsp, kPointerSize)); 4254 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, kPointerSize));
4255 // Copy of key, needed for later store. 4255 // Copy of key, needed for later store.
4256 __ movp(LoadConvention::NameRegister(), Operand(rsp, 0)); 4256 __ movp(LoadDescriptor::NameRegister(), Operand(rsp, 0));
4257 EmitKeyedPropertyLoad(prop); 4257 EmitKeyedPropertyLoad(prop);
4258 } 4258 }
4259 } 4259 }
4260 4260
4261 // We need a second deoptimization point after loading the value 4261 // We need a second deoptimization point after loading the value
4262 // in case evaluating the property load my have a side effect. 4262 // in case evaluating the property load my have a side effect.
4263 if (assign_type == VARIABLE) { 4263 if (assign_type == VARIABLE) {
4264 PrepareForBailout(expr->expression(), TOS_REG); 4264 PrepareForBailout(expr->expression(), TOS_REG);
4265 } else { 4265 } else {
4266 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 4266 PrepareForBailoutForId(prop->LoadId(), TOS_REG);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
4358 } 4358 }
4359 } else { 4359 } else {
4360 // Perform the assignment as if via '='. 4360 // Perform the assignment as if via '='.
4361 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 4361 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
4362 Token::ASSIGN); 4362 Token::ASSIGN);
4363 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4363 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4364 context()->Plug(rax); 4364 context()->Plug(rax);
4365 } 4365 }
4366 break; 4366 break;
4367 case NAMED_PROPERTY: { 4367 case NAMED_PROPERTY: {
4368 __ Move(StoreConvention::NameRegister(), 4368 __ Move(StoreDescriptor::NameRegister(),
4369 prop->key()->AsLiteral()->value()); 4369 prop->key()->AsLiteral()->value());
4370 __ Pop(StoreConvention::ReceiverRegister()); 4370 __ Pop(StoreDescriptor::ReceiverRegister());
4371 CallStoreIC(expr->CountStoreFeedbackId()); 4371 CallStoreIC(expr->CountStoreFeedbackId());
4372 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4372 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4373 if (expr->is_postfix()) { 4373 if (expr->is_postfix()) {
4374 if (!context()->IsEffect()) { 4374 if (!context()->IsEffect()) {
4375 context()->PlugTOS(); 4375 context()->PlugTOS();
4376 } 4376 }
4377 } else { 4377 } else {
4378 context()->Plug(rax); 4378 context()->Plug(rax);
4379 } 4379 }
4380 break; 4380 break;
4381 } 4381 }
4382 case KEYED_PROPERTY: { 4382 case KEYED_PROPERTY: {
4383 __ Pop(StoreConvention::NameRegister()); 4383 __ Pop(StoreDescriptor::NameRegister());
4384 __ Pop(StoreConvention::ReceiverRegister()); 4384 __ Pop(StoreDescriptor::ReceiverRegister());
4385 Handle<Code> ic = strict_mode() == SLOPPY 4385 Handle<Code> ic = strict_mode() == SLOPPY
4386 ? isolate()->builtins()->KeyedStoreIC_Initialize() 4386 ? isolate()->builtins()->KeyedStoreIC_Initialize()
4387 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 4387 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
4388 CallIC(ic, expr->CountStoreFeedbackId()); 4388 CallIC(ic, expr->CountStoreFeedbackId());
4389 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4389 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4390 if (expr->is_postfix()) { 4390 if (expr->is_postfix()) {
4391 if (!context()->IsEffect()) { 4391 if (!context()->IsEffect()) {
4392 context()->PlugTOS(); 4392 context()->PlugTOS();
4393 } 4393 }
4394 } else { 4394 } else {
4395 context()->Plug(rax); 4395 context()->Plug(rax);
4396 } 4396 }
4397 break; 4397 break;
4398 } 4398 }
4399 } 4399 }
4400 } 4400 }
4401 4401
4402 4402
4403 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { 4403 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
4404 VariableProxy* proxy = expr->AsVariableProxy(); 4404 VariableProxy* proxy = expr->AsVariableProxy();
4405 DCHECK(!context()->IsEffect()); 4405 DCHECK(!context()->IsEffect());
4406 DCHECK(!context()->IsTest()); 4406 DCHECK(!context()->IsTest());
4407 4407
4408 if (proxy != NULL && proxy->var()->IsUnallocated()) { 4408 if (proxy != NULL && proxy->var()->IsUnallocated()) {
4409 Comment cmnt(masm_, "[ Global variable"); 4409 Comment cmnt(masm_, "[ Global variable");
4410 __ Move(LoadConvention::NameRegister(), proxy->name()); 4410 __ Move(LoadDescriptor::NameRegister(), proxy->name());
4411 __ movp(LoadConvention::ReceiverRegister(), GlobalObjectOperand()); 4411 __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
4412 if (FLAG_vector_ics) { 4412 if (FLAG_vector_ics) {
4413 __ Move(VectorLoadConvention::SlotRegister(), 4413 __ Move(VectorLoadICDescriptor::SlotRegister(),
4414 Smi::FromInt(proxy->VariableFeedbackSlot())); 4414 Smi::FromInt(proxy->VariableFeedbackSlot()));
4415 } 4415 }
4416 // Use a regular load, not a contextual load, to avoid a reference 4416 // Use a regular load, not a contextual load, to avoid a reference
4417 // error. 4417 // error.
4418 CallLoadIC(NOT_CONTEXTUAL); 4418 CallLoadIC(NOT_CONTEXTUAL);
4419 PrepareForBailout(expr, TOS_REG); 4419 PrepareForBailout(expr, TOS_REG);
4420 context()->Plug(rax); 4420 context()->Plug(rax);
4421 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { 4421 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
4422 Comment cmnt(masm_, "[ Lookup slot"); 4422 Comment cmnt(masm_, "[ Lookup slot");
4423 Label done, slow; 4423 Label done, slow;
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
4836 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), 4836 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(),
4837 Assembler::target_address_at(call_target_address, 4837 Assembler::target_address_at(call_target_address,
4838 unoptimized_code)); 4838 unoptimized_code));
4839 return OSR_AFTER_STACK_CHECK; 4839 return OSR_AFTER_STACK_CHECK;
4840 } 4840 }
4841 4841
4842 4842
4843 } } // namespace v8::internal 4843 } } // namespace v8::internal
4844 4844
4845 #endif // V8_TARGET_ARCH_X64 4845 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698