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

Side by Side Diff: src/arm/full-codegen-arm.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_ARM 7 #if V8_TARGET_ARCH_ARM
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 1384 matching lines...) Expand 10 before | Expand all | Expand 10 after
1395 // Check that extension is NULL. 1395 // Check that extension is NULL.
1396 __ ldr(temp, ContextOperand(next, Context::EXTENSION_INDEX)); 1396 __ ldr(temp, ContextOperand(next, Context::EXTENSION_INDEX));
1397 __ tst(temp, temp); 1397 __ tst(temp, temp);
1398 __ b(ne, slow); 1398 __ b(ne, slow);
1399 // Load next context in chain. 1399 // Load next context in chain.
1400 __ ldr(next, ContextOperand(next, Context::PREVIOUS_INDEX)); 1400 __ ldr(next, ContextOperand(next, Context::PREVIOUS_INDEX));
1401 __ b(&loop); 1401 __ b(&loop);
1402 __ bind(&fast); 1402 __ bind(&fast);
1403 } 1403 }
1404 1404
1405 __ ldr(LoadConvention::ReceiverRegister(), GlobalObjectOperand()); 1405 __ ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
1406 __ mov(LoadConvention::NameRegister(), Operand(proxy->var()->name())); 1406 __ mov(LoadDescriptor::NameRegister(), Operand(proxy->var()->name()));
1407 if (FLAG_vector_ics) { 1407 if (FLAG_vector_ics) {
1408 __ mov(VectorLoadConvention::SlotRegister(), 1408 __ mov(VectorLoadICDescriptor::SlotRegister(),
1409 Operand(Smi::FromInt(proxy->VariableFeedbackSlot()))); 1409 Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
1410 } 1410 }
1411 1411
1412 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) 1412 ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
1413 ? NOT_CONTEXTUAL 1413 ? NOT_CONTEXTUAL
1414 : CONTEXTUAL; 1414 : CONTEXTUAL;
1415 CallLoadIC(mode); 1415 CallLoadIC(mode);
1416 } 1416 }
1417 1417
1418 1418
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1484 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { 1484 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
1485 // Record position before possible IC call. 1485 // Record position before possible IC call.
1486 SetSourcePosition(proxy->position()); 1486 SetSourcePosition(proxy->position());
1487 Variable* var = proxy->var(); 1487 Variable* var = proxy->var();
1488 1488
1489 // Three cases: global variables, lookup variables, and all other types of 1489 // Three cases: global variables, lookup variables, and all other types of
1490 // variables. 1490 // variables.
1491 switch (var->location()) { 1491 switch (var->location()) {
1492 case Variable::UNALLOCATED: { 1492 case Variable::UNALLOCATED: {
1493 Comment cmnt(masm_, "[ Global variable"); 1493 Comment cmnt(masm_, "[ Global variable");
1494 __ ldr(LoadConvention::ReceiverRegister(), GlobalObjectOperand()); 1494 __ ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
1495 __ mov(LoadConvention::NameRegister(), Operand(var->name())); 1495 __ mov(LoadDescriptor::NameRegister(), Operand(var->name()));
1496 if (FLAG_vector_ics) { 1496 if (FLAG_vector_ics) {
1497 __ mov(VectorLoadConvention::SlotRegister(), 1497 __ mov(VectorLoadICDescriptor::SlotRegister(),
1498 Operand(Smi::FromInt(proxy->VariableFeedbackSlot()))); 1498 Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
1499 } 1499 }
1500 CallLoadIC(CONTEXTUAL); 1500 CallLoadIC(CONTEXTUAL);
1501 context()->Plug(r0); 1501 context()->Plug(r0);
1502 break; 1502 break;
1503 } 1503 }
1504 1504
1505 case Variable::PARAMETER: 1505 case Variable::PARAMETER:
1506 case Variable::LOCAL: 1506 case Variable::LOCAL:
1507 case Variable::CONTEXT: { 1507 case Variable::CONTEXT: {
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
1695 switch (property->kind()) { 1695 switch (property->kind()) {
1696 case ObjectLiteral::Property::CONSTANT: 1696 case ObjectLiteral::Property::CONSTANT:
1697 UNREACHABLE(); 1697 UNREACHABLE();
1698 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1698 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1699 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); 1699 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
1700 // Fall through. 1700 // Fall through.
1701 case ObjectLiteral::Property::COMPUTED: 1701 case ObjectLiteral::Property::COMPUTED:
1702 if (key->value()->IsInternalizedString()) { 1702 if (key->value()->IsInternalizedString()) {
1703 if (property->emit_store()) { 1703 if (property->emit_store()) {
1704 VisitForAccumulatorValue(value); 1704 VisitForAccumulatorValue(value);
1705 DCHECK(StoreConvention::ValueRegister().is(r0)); 1705 DCHECK(StoreDescriptor::ValueRegister().is(r0));
1706 __ mov(StoreConvention::NameRegister(), Operand(key->value())); 1706 __ mov(StoreDescriptor::NameRegister(), Operand(key->value()));
1707 __ ldr(StoreConvention::ReceiverRegister(), MemOperand(sp)); 1707 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
1708 CallStoreIC(key->LiteralFeedbackId()); 1708 CallStoreIC(key->LiteralFeedbackId());
1709 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1709 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1710 } else { 1710 } else {
1711 VisitForEffect(value); 1711 VisitForEffect(value);
1712 } 1712 }
1713 break; 1713 break;
1714 } 1714 }
1715 // Duplicate receiver on stack. 1715 // Duplicate receiver on stack.
1716 __ ldr(r0, MemOperand(sp)); 1716 __ ldr(r0, MemOperand(sp));
1717 __ push(r0); 1717 __ push(r0);
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1876 1876
1877 // Evaluate LHS expression. 1877 // Evaluate LHS expression.
1878 switch (assign_type) { 1878 switch (assign_type) {
1879 case VARIABLE: 1879 case VARIABLE:
1880 // Nothing to do here. 1880 // Nothing to do here.
1881 break; 1881 break;
1882 case NAMED_PROPERTY: 1882 case NAMED_PROPERTY:
1883 if (expr->is_compound()) { 1883 if (expr->is_compound()) {
1884 // We need the receiver both on the stack and in the register. 1884 // We need the receiver both on the stack and in the register.
1885 VisitForStackValue(property->obj()); 1885 VisitForStackValue(property->obj());
1886 __ ldr(LoadConvention::ReceiverRegister(), MemOperand(sp, 0)); 1886 __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
1887 } else { 1887 } else {
1888 VisitForStackValue(property->obj()); 1888 VisitForStackValue(property->obj());
1889 } 1889 }
1890 break; 1890 break;
1891 case KEYED_PROPERTY: 1891 case KEYED_PROPERTY:
1892 if (expr->is_compound()) { 1892 if (expr->is_compound()) {
1893 VisitForStackValue(property->obj()); 1893 VisitForStackValue(property->obj());
1894 VisitForStackValue(property->key()); 1894 VisitForStackValue(property->key());
1895 __ ldr(LoadConvention::ReceiverRegister(), 1895 __ ldr(LoadDescriptor::ReceiverRegister(),
1896 MemOperand(sp, 1 * kPointerSize)); 1896 MemOperand(sp, 1 * kPointerSize));
1897 __ ldr(LoadConvention::NameRegister(), MemOperand(sp, 0)); 1897 __ ldr(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
1898 } else { 1898 } else {
1899 VisitForStackValue(property->obj()); 1899 VisitForStackValue(property->obj());
1900 VisitForStackValue(property->key()); 1900 VisitForStackValue(property->key());
1901 } 1901 }
1902 break; 1902 break;
1903 } 1903 }
1904 1904
1905 // For compound assignments we need another deoptimization point after the 1905 // For compound assignments we need another deoptimization point after the
1906 // variable/property load. 1906 // variable/property load.
1907 if (expr->is_compound()) { 1907 if (expr->is_compound()) {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
2026 2026
2027 case Yield::kDelegating: { 2027 case Yield::kDelegating: {
2028 VisitForStackValue(expr->generator_object()); 2028 VisitForStackValue(expr->generator_object());
2029 2029
2030 // Initial stack layout is as follows: 2030 // Initial stack layout is as follows:
2031 // [sp + 1 * kPointerSize] iter 2031 // [sp + 1 * kPointerSize] iter
2032 // [sp + 0 * kPointerSize] g 2032 // [sp + 0 * kPointerSize] g
2033 2033
2034 Label l_catch, l_try, l_suspend, l_continuation, l_resume; 2034 Label l_catch, l_try, l_suspend, l_continuation, l_resume;
2035 Label l_next, l_call, l_loop; 2035 Label l_next, l_call, l_loop;
2036 Register load_receiver = LoadConvention::ReceiverRegister(); 2036 Register load_receiver = LoadDescriptor::ReceiverRegister();
2037 Register load_name = LoadConvention::NameRegister(); 2037 Register load_name = LoadDescriptor::NameRegister();
2038 2038
2039 // Initial send value is undefined. 2039 // Initial send value is undefined.
2040 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 2040 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
2041 __ b(&l_next); 2041 __ b(&l_next);
2042 2042
2043 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } 2043 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; }
2044 __ bind(&l_catch); 2044 __ bind(&l_catch);
2045 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); 2045 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
2046 __ LoadRoot(load_name, Heap::kthrow_stringRootIndex); // "throw" 2046 __ LoadRoot(load_name, Heap::kthrow_stringRootIndex); // "throw"
2047 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter 2047 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2082 2082
2083 __ LoadRoot(load_name, Heap::knext_stringRootIndex); // "next" 2083 __ LoadRoot(load_name, Heap::knext_stringRootIndex); // "next"
2084 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter 2084 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter
2085 __ Push(load_name, r3, r0); // "next", iter, received 2085 __ Push(load_name, r3, r0); // "next", iter, received
2086 2086
2087 // result = receiver[f](arg); 2087 // result = receiver[f](arg);
2088 __ bind(&l_call); 2088 __ bind(&l_call);
2089 __ ldr(load_receiver, MemOperand(sp, kPointerSize)); 2089 __ ldr(load_receiver, MemOperand(sp, kPointerSize));
2090 __ ldr(load_name, MemOperand(sp, 2 * kPointerSize)); 2090 __ ldr(load_name, MemOperand(sp, 2 * kPointerSize));
2091 if (FLAG_vector_ics) { 2091 if (FLAG_vector_ics) {
2092 __ mov(VectorLoadConvention::SlotRegister(), 2092 __ mov(VectorLoadICDescriptor::SlotRegister(),
2093 Operand(Smi::FromInt(expr->KeyedLoadFeedbackSlot()))); 2093 Operand(Smi::FromInt(expr->KeyedLoadFeedbackSlot())));
2094 } 2094 }
2095 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2095 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2096 CallIC(ic, TypeFeedbackId::None()); 2096 CallIC(ic, TypeFeedbackId::None());
2097 __ mov(r1, r0); 2097 __ mov(r1, r0);
2098 __ str(r1, MemOperand(sp, 2 * kPointerSize)); 2098 __ str(r1, MemOperand(sp, 2 * kPointerSize));
2099 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); 2099 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD);
2100 __ CallStub(&stub); 2100 __ CallStub(&stub);
2101 2101
2102 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2102 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2103 __ Drop(1); // The function is still on the stack; drop it. 2103 __ Drop(1); // The function is still on the stack; drop it.
2104 2104
2105 // if (!result.done) goto l_try; 2105 // if (!result.done) goto l_try;
2106 __ bind(&l_loop); 2106 __ bind(&l_loop);
2107 __ Move(load_receiver, r0); 2107 __ Move(load_receiver, r0);
2108 2108
2109 __ push(load_receiver); // save result 2109 __ push(load_receiver); // save result
2110 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" 2110 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
2111 if (FLAG_vector_ics) { 2111 if (FLAG_vector_ics) {
2112 __ mov(VectorLoadConvention::SlotRegister(), 2112 __ mov(VectorLoadICDescriptor::SlotRegister(),
2113 Operand(Smi::FromInt(expr->DoneFeedbackSlot()))); 2113 Operand(Smi::FromInt(expr->DoneFeedbackSlot())));
2114 } 2114 }
2115 CallLoadIC(NOT_CONTEXTUAL); // r0=result.done 2115 CallLoadIC(NOT_CONTEXTUAL); // r0=result.done
2116 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); 2116 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
2117 CallIC(bool_ic); 2117 CallIC(bool_ic);
2118 __ cmp(r0, Operand(0)); 2118 __ cmp(r0, Operand(0));
2119 __ b(eq, &l_try); 2119 __ b(eq, &l_try);
2120 2120
2121 // result.value 2121 // result.value
2122 __ pop(load_receiver); // result 2122 __ pop(load_receiver); // result
2123 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" 2123 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
2124 if (FLAG_vector_ics) { 2124 if (FLAG_vector_ics) {
2125 __ mov(VectorLoadConvention::SlotRegister(), 2125 __ mov(VectorLoadICDescriptor::SlotRegister(),
2126 Operand(Smi::FromInt(expr->ValueFeedbackSlot()))); 2126 Operand(Smi::FromInt(expr->ValueFeedbackSlot())));
2127 } 2127 }
2128 CallLoadIC(NOT_CONTEXTUAL); // r0=result.value 2128 CallLoadIC(NOT_CONTEXTUAL); // r0=result.value
2129 context()->DropAndPlug(2, r0); // drop iter and g 2129 context()->DropAndPlug(2, r0); // drop iter and g
2130 break; 2130 break;
2131 } 2131 }
2132 } 2132 }
2133 } 2133 }
2134 2134
2135 2135
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
2292 // Only the value field needs a write barrier, as the other values are in the 2292 // Only the value field needs a write barrier, as the other values are in the
2293 // root set. 2293 // root set.
2294 __ RecordWriteField(r0, JSGeneratorObject::kResultValuePropertyOffset, 2294 __ RecordWriteField(r0, JSGeneratorObject::kResultValuePropertyOffset,
2295 r2, r3, kLRHasBeenSaved, kDontSaveFPRegs); 2295 r2, r3, kLRHasBeenSaved, kDontSaveFPRegs);
2296 } 2296 }
2297 2297
2298 2298
2299 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 2299 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
2300 SetSourcePosition(prop->position()); 2300 SetSourcePosition(prop->position());
2301 Literal* key = prop->key()->AsLiteral(); 2301 Literal* key = prop->key()->AsLiteral();
2302 __ mov(LoadConvention::NameRegister(), Operand(key->value())); 2302 __ mov(LoadDescriptor::NameRegister(), Operand(key->value()));
2303 if (FLAG_vector_ics) { 2303 if (FLAG_vector_ics) {
2304 __ mov(VectorLoadConvention::SlotRegister(), 2304 __ mov(VectorLoadICDescriptor::SlotRegister(),
2305 Operand(Smi::FromInt(prop->PropertyFeedbackSlot()))); 2305 Operand(Smi::FromInt(prop->PropertyFeedbackSlot())));
2306 CallLoadIC(NOT_CONTEXTUAL); 2306 CallLoadIC(NOT_CONTEXTUAL);
2307 } else { 2307 } else {
2308 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); 2308 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
2309 } 2309 }
2310 } 2310 }
2311 2311
2312 2312
2313 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 2313 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2314 SetSourcePosition(prop->position()); 2314 SetSourcePosition(prop->position());
2315 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2315 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2316 if (FLAG_vector_ics) { 2316 if (FLAG_vector_ics) {
2317 __ mov(VectorLoadConvention::SlotRegister(), 2317 __ mov(VectorLoadICDescriptor::SlotRegister(),
2318 Operand(Smi::FromInt(prop->PropertyFeedbackSlot()))); 2318 Operand(Smi::FromInt(prop->PropertyFeedbackSlot())));
2319 CallIC(ic); 2319 CallIC(ic);
2320 } else { 2320 } else {
2321 CallIC(ic, prop->PropertyFeedbackId()); 2321 CallIC(ic, prop->PropertyFeedbackId());
2322 } 2322 }
2323 } 2323 }
2324 2324
2325 2325
2326 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2326 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
2327 Token::Value op, 2327 Token::Value op,
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
2446 switch (assign_type) { 2446 switch (assign_type) {
2447 case VARIABLE: { 2447 case VARIABLE: {
2448 Variable* var = expr->AsVariableProxy()->var(); 2448 Variable* var = expr->AsVariableProxy()->var();
2449 EffectContext context(this); 2449 EffectContext context(this);
2450 EmitVariableAssignment(var, Token::ASSIGN); 2450 EmitVariableAssignment(var, Token::ASSIGN);
2451 break; 2451 break;
2452 } 2452 }
2453 case NAMED_PROPERTY: { 2453 case NAMED_PROPERTY: {
2454 __ push(r0); // Preserve value. 2454 __ push(r0); // Preserve value.
2455 VisitForAccumulatorValue(prop->obj()); 2455 VisitForAccumulatorValue(prop->obj());
2456 __ Move(StoreConvention::ReceiverRegister(), r0); 2456 __ Move(StoreDescriptor::ReceiverRegister(), r0);
2457 __ pop(StoreConvention::ValueRegister()); // Restore value. 2457 __ pop(StoreDescriptor::ValueRegister()); // Restore value.
2458 __ mov(StoreConvention::NameRegister(), 2458 __ mov(StoreDescriptor::NameRegister(),
2459 Operand(prop->key()->AsLiteral()->value())); 2459 Operand(prop->key()->AsLiteral()->value()));
2460 CallStoreIC(); 2460 CallStoreIC();
2461 break; 2461 break;
2462 } 2462 }
2463 case KEYED_PROPERTY: { 2463 case KEYED_PROPERTY: {
2464 __ push(r0); // Preserve value. 2464 __ push(r0); // Preserve value.
2465 VisitForStackValue(prop->obj()); 2465 VisitForStackValue(prop->obj());
2466 VisitForAccumulatorValue(prop->key()); 2466 VisitForAccumulatorValue(prop->key());
2467 __ Move(StoreConvention::NameRegister(), r0); 2467 __ Move(StoreDescriptor::NameRegister(), r0);
2468 __ Pop(StoreConvention::ValueRegister(), 2468 __ Pop(StoreDescriptor::ValueRegister(),
2469 StoreConvention::ReceiverRegister()); 2469 StoreDescriptor::ReceiverRegister());
2470 Handle<Code> ic = strict_mode() == SLOPPY 2470 Handle<Code> ic = strict_mode() == SLOPPY
2471 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2471 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2472 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2472 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2473 CallIC(ic); 2473 CallIC(ic);
2474 break; 2474 break;
2475 } 2475 }
2476 } 2476 }
2477 context()->Plug(r0); 2477 context()->Plug(r0);
2478 } 2478 }
2479 2479
2480 2480
2481 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( 2481 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
2482 Variable* var, MemOperand location) { 2482 Variable* var, MemOperand location) {
2483 __ str(result_register(), location); 2483 __ str(result_register(), location);
2484 if (var->IsContextSlot()) { 2484 if (var->IsContextSlot()) {
2485 // RecordWrite may destroy all its register arguments. 2485 // RecordWrite may destroy all its register arguments.
2486 __ mov(r3, result_register()); 2486 __ mov(r3, result_register());
2487 int offset = Context::SlotOffset(var->index()); 2487 int offset = Context::SlotOffset(var->index());
2488 __ RecordWriteContextSlot( 2488 __ RecordWriteContextSlot(
2489 r1, offset, r3, r2, kLRHasBeenSaved, kDontSaveFPRegs); 2489 r1, offset, r3, r2, kLRHasBeenSaved, kDontSaveFPRegs);
2490 } 2490 }
2491 } 2491 }
2492 2492
2493 2493
2494 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) { 2494 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) {
2495 if (var->IsUnallocated()) { 2495 if (var->IsUnallocated()) {
2496 // Global var, const, or let. 2496 // Global var, const, or let.
2497 __ mov(StoreConvention::NameRegister(), Operand(var->name())); 2497 __ mov(StoreDescriptor::NameRegister(), Operand(var->name()));
2498 __ ldr(StoreConvention::ReceiverRegister(), GlobalObjectOperand()); 2498 __ ldr(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand());
2499 CallStoreIC(); 2499 CallStoreIC();
2500 2500
2501 } else if (op == Token::INIT_CONST_LEGACY) { 2501 } else if (op == Token::INIT_CONST_LEGACY) {
2502 // Const initializers need a write barrier. 2502 // Const initializers need a write barrier.
2503 DCHECK(!var->IsParameter()); // No const parameters. 2503 DCHECK(!var->IsParameter()); // No const parameters.
2504 if (var->IsLookupSlot()) { 2504 if (var->IsLookupSlot()) {
2505 __ push(r0); 2505 __ push(r0);
2506 __ mov(r0, Operand(var->name())); 2506 __ mov(r0, Operand(var->name()));
2507 __ Push(cp, r0); // Context and name. 2507 __ Push(cp, r0); // Context and name.
2508 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); 2508 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2560 2560
2561 2561
2562 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2562 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2563 // Assignment to a property, using a named store IC. 2563 // Assignment to a property, using a named store IC.
2564 Property* prop = expr->target()->AsProperty(); 2564 Property* prop = expr->target()->AsProperty();
2565 DCHECK(prop != NULL); 2565 DCHECK(prop != NULL);
2566 DCHECK(prop->key()->IsLiteral()); 2566 DCHECK(prop->key()->IsLiteral());
2567 2567
2568 // Record source code position before IC call. 2568 // Record source code position before IC call.
2569 SetSourcePosition(expr->position()); 2569 SetSourcePosition(expr->position());
2570 __ mov(StoreConvention::NameRegister(), 2570 __ mov(StoreDescriptor::NameRegister(),
2571 Operand(prop->key()->AsLiteral()->value())); 2571 Operand(prop->key()->AsLiteral()->value()));
2572 __ pop(StoreConvention::ReceiverRegister()); 2572 __ pop(StoreDescriptor::ReceiverRegister());
2573 CallStoreIC(expr->AssignmentFeedbackId()); 2573 CallStoreIC(expr->AssignmentFeedbackId());
2574 2574
2575 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2575 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2576 context()->Plug(r0); 2576 context()->Plug(r0);
2577 } 2577 }
2578 2578
2579 2579
2580 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2580 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2581 // Assignment to a property, using a keyed store IC. 2581 // Assignment to a property, using a keyed store IC.
2582 2582
2583 // Record source code position before IC call. 2583 // Record source code position before IC call.
2584 SetSourcePosition(expr->position()); 2584 SetSourcePosition(expr->position());
2585 __ Pop(StoreConvention::ReceiverRegister(), StoreConvention::NameRegister()); 2585 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister());
2586 DCHECK(StoreConvention::ValueRegister().is(r0)); 2586 DCHECK(StoreDescriptor::ValueRegister().is(r0));
2587 2587
2588 Handle<Code> ic = strict_mode() == SLOPPY 2588 Handle<Code> ic = strict_mode() == SLOPPY
2589 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2589 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2590 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2590 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2591 CallIC(ic, expr->AssignmentFeedbackId()); 2591 CallIC(ic, expr->AssignmentFeedbackId());
2592 2592
2593 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2593 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2594 context()->Plug(r0); 2594 context()->Plug(r0);
2595 } 2595 }
2596 2596
2597 2597
2598 void FullCodeGenerator::VisitProperty(Property* expr) { 2598 void FullCodeGenerator::VisitProperty(Property* expr) {
2599 Comment cmnt(masm_, "[ Property"); 2599 Comment cmnt(masm_, "[ Property");
2600 Expression* key = expr->key(); 2600 Expression* key = expr->key();
2601 2601
2602 if (key->IsPropertyName()) { 2602 if (key->IsPropertyName()) {
2603 VisitForAccumulatorValue(expr->obj()); 2603 VisitForAccumulatorValue(expr->obj());
2604 __ Move(LoadConvention::ReceiverRegister(), r0); 2604 __ Move(LoadDescriptor::ReceiverRegister(), r0);
2605 EmitNamedPropertyLoad(expr); 2605 EmitNamedPropertyLoad(expr);
2606 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2606 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
2607 context()->Plug(r0); 2607 context()->Plug(r0);
2608 } else { 2608 } else {
2609 VisitForStackValue(expr->obj()); 2609 VisitForStackValue(expr->obj());
2610 VisitForAccumulatorValue(expr->key()); 2610 VisitForAccumulatorValue(expr->key());
2611 __ Move(LoadConvention::NameRegister(), r0); 2611 __ Move(LoadDescriptor::NameRegister(), r0);
2612 __ pop(LoadConvention::ReceiverRegister()); 2612 __ pop(LoadDescriptor::ReceiverRegister());
2613 EmitKeyedPropertyLoad(expr); 2613 EmitKeyedPropertyLoad(expr);
2614 context()->Plug(r0); 2614 context()->Plug(r0);
2615 } 2615 }
2616 } 2616 }
2617 2617
2618 2618
2619 void FullCodeGenerator::CallIC(Handle<Code> code, 2619 void FullCodeGenerator::CallIC(Handle<Code> code,
2620 TypeFeedbackId ast_id) { 2620 TypeFeedbackId ast_id) {
2621 ic_total_count_++; 2621 ic_total_count_++;
2622 // All calls must have a predictable size in full-codegen code to ensure that 2622 // All calls must have a predictable size in full-codegen code to ensure that
(...skipping 16 matching lines...) Expand all
2639 { StackValueContext context(this); 2639 { StackValueContext context(this);
2640 EmitVariableLoad(callee->AsVariableProxy()); 2640 EmitVariableLoad(callee->AsVariableProxy());
2641 PrepareForBailout(callee, NO_REGISTERS); 2641 PrepareForBailout(callee, NO_REGISTERS);
2642 } 2642 }
2643 // Push undefined as receiver. This is patched in the method prologue if it 2643 // Push undefined as receiver. This is patched in the method prologue if it
2644 // is a sloppy mode method. 2644 // is a sloppy mode method.
2645 __ Push(isolate()->factory()->undefined_value()); 2645 __ Push(isolate()->factory()->undefined_value());
2646 } else { 2646 } else {
2647 // Load the function from the receiver. 2647 // Load the function from the receiver.
2648 DCHECK(callee->IsProperty()); 2648 DCHECK(callee->IsProperty());
2649 __ ldr(LoadConvention::ReceiverRegister(), MemOperand(sp, 0)); 2649 __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
2650 EmitNamedPropertyLoad(callee->AsProperty()); 2650 EmitNamedPropertyLoad(callee->AsProperty());
2651 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2651 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2652 // Push the target function under the receiver. 2652 // Push the target function under the receiver.
2653 __ ldr(ip, MemOperand(sp, 0)); 2653 __ ldr(ip, MemOperand(sp, 0));
2654 __ push(ip); 2654 __ push(ip);
2655 __ str(r0, MemOperand(sp, kPointerSize)); 2655 __ str(r0, MemOperand(sp, kPointerSize));
2656 } 2656 }
2657 2657
2658 EmitCall(expr, call_type); 2658 EmitCall(expr, call_type);
2659 } 2659 }
2660 2660
2661 2661
2662 // Code common for calls using the IC. 2662 // Code common for calls using the IC.
2663 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2663 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2664 Expression* key) { 2664 Expression* key) {
2665 // Load the key. 2665 // Load the key.
2666 VisitForAccumulatorValue(key); 2666 VisitForAccumulatorValue(key);
2667 2667
2668 Expression* callee = expr->expression(); 2668 Expression* callee = expr->expression();
2669 2669
2670 // Load the function from the receiver. 2670 // Load the function from the receiver.
2671 DCHECK(callee->IsProperty()); 2671 DCHECK(callee->IsProperty());
2672 __ ldr(LoadConvention::ReceiverRegister(), MemOperand(sp, 0)); 2672 __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
2673 __ Move(LoadConvention::NameRegister(), r0); 2673 __ Move(LoadDescriptor::NameRegister(), r0);
2674 EmitKeyedPropertyLoad(callee->AsProperty()); 2674 EmitKeyedPropertyLoad(callee->AsProperty());
2675 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2675 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2676 2676
2677 // Push the target function under the receiver. 2677 // Push the target function under the receiver.
2678 __ ldr(ip, MemOperand(sp, 0)); 2678 __ ldr(ip, MemOperand(sp, 0));
2679 __ push(ip); 2679 __ push(ip);
2680 __ str(r0, MemOperand(sp, kPointerSize)); 2680 __ str(r0, MemOperand(sp, kPointerSize));
2681 2681
2682 EmitCall(expr, CallIC::METHOD); 2682 EmitCall(expr, CallIC::METHOD);
2683 } 2683 }
(...skipping 1392 matching lines...) Expand 10 before | Expand all | Expand 10 after
4076 EmitInlineRuntimeCall(expr); 4076 EmitInlineRuntimeCall(expr);
4077 return; 4077 return;
4078 } 4078 }
4079 4079
4080 Comment cmnt(masm_, "[ CallRuntime"); 4080 Comment cmnt(masm_, "[ CallRuntime");
4081 ZoneList<Expression*>* args = expr->arguments(); 4081 ZoneList<Expression*>* args = expr->arguments();
4082 int arg_count = args->length(); 4082 int arg_count = args->length();
4083 4083
4084 if (expr->is_jsruntime()) { 4084 if (expr->is_jsruntime()) {
4085 // Push the builtins object as the receiver. 4085 // Push the builtins object as the receiver.
4086 Register receiver = LoadConvention::ReceiverRegister(); 4086 Register receiver = LoadDescriptor::ReceiverRegister();
4087 __ ldr(receiver, GlobalObjectOperand()); 4087 __ ldr(receiver, GlobalObjectOperand());
4088 __ ldr(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset)); 4088 __ ldr(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset));
4089 __ push(receiver); 4089 __ push(receiver);
4090 4090
4091 // Load the function from the receiver. 4091 // Load the function from the receiver.
4092 __ mov(LoadConvention::NameRegister(), Operand(expr->name())); 4092 __ mov(LoadDescriptor::NameRegister(), Operand(expr->name()));
4093 if (FLAG_vector_ics) { 4093 if (FLAG_vector_ics) {
4094 __ mov(VectorLoadConvention::SlotRegister(), 4094 __ mov(VectorLoadICDescriptor::SlotRegister(),
4095 Operand(Smi::FromInt(expr->CallRuntimeFeedbackSlot()))); 4095 Operand(Smi::FromInt(expr->CallRuntimeFeedbackSlot())));
4096 CallLoadIC(NOT_CONTEXTUAL); 4096 CallLoadIC(NOT_CONTEXTUAL);
4097 } else { 4097 } else {
4098 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); 4098 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
4099 } 4099 }
4100 4100
4101 // Push the target function under the receiver. 4101 // Push the target function under the receiver.
4102 __ ldr(ip, MemOperand(sp, 0)); 4102 __ ldr(ip, MemOperand(sp, 0));
4103 __ push(ip); 4103 __ push(ip);
4104 __ str(r0, MemOperand(sp, kPointerSize)); 4104 __ str(r0, MemOperand(sp, kPointerSize));
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
4267 EmitVariableLoad(expr->expression()->AsVariableProxy()); 4267 EmitVariableLoad(expr->expression()->AsVariableProxy());
4268 } else { 4268 } else {
4269 // Reserve space for result of postfix operation. 4269 // Reserve space for result of postfix operation.
4270 if (expr->is_postfix() && !context()->IsEffect()) { 4270 if (expr->is_postfix() && !context()->IsEffect()) {
4271 __ mov(ip, Operand(Smi::FromInt(0))); 4271 __ mov(ip, Operand(Smi::FromInt(0)));
4272 __ push(ip); 4272 __ push(ip);
4273 } 4273 }
4274 if (assign_type == NAMED_PROPERTY) { 4274 if (assign_type == NAMED_PROPERTY) {
4275 // Put the object both on the stack and in the register. 4275 // Put the object both on the stack and in the register.
4276 VisitForStackValue(prop->obj()); 4276 VisitForStackValue(prop->obj());
4277 __ ldr(LoadConvention::ReceiverRegister(), MemOperand(sp, 0)); 4277 __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
4278 EmitNamedPropertyLoad(prop); 4278 EmitNamedPropertyLoad(prop);
4279 } else { 4279 } else {
4280 VisitForStackValue(prop->obj()); 4280 VisitForStackValue(prop->obj());
4281 VisitForStackValue(prop->key()); 4281 VisitForStackValue(prop->key());
4282 __ ldr(LoadConvention::ReceiverRegister(), 4282 __ ldr(LoadDescriptor::ReceiverRegister(),
4283 MemOperand(sp, 1 * kPointerSize)); 4283 MemOperand(sp, 1 * kPointerSize));
4284 __ ldr(LoadConvention::NameRegister(), MemOperand(sp, 0)); 4284 __ ldr(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
4285 EmitKeyedPropertyLoad(prop); 4285 EmitKeyedPropertyLoad(prop);
4286 } 4286 }
4287 } 4287 }
4288 4288
4289 // We need a second deoptimization point after loading the value 4289 // We need a second deoptimization point after loading the value
4290 // in case evaluating the property load my have a side effect. 4290 // in case evaluating the property load my have a side effect.
4291 if (assign_type == VARIABLE) { 4291 if (assign_type == VARIABLE) {
4292 PrepareForBailout(expr->expression(), TOS_REG); 4292 PrepareForBailout(expr->expression(), TOS_REG);
4293 } else { 4293 } else {
4294 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 4294 PrepareForBailoutForId(prop->LoadId(), TOS_REG);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
4382 context()->PlugTOS(); 4382 context()->PlugTOS();
4383 } 4383 }
4384 } else { 4384 } else {
4385 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 4385 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
4386 Token::ASSIGN); 4386 Token::ASSIGN);
4387 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4387 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4388 context()->Plug(r0); 4388 context()->Plug(r0);
4389 } 4389 }
4390 break; 4390 break;
4391 case NAMED_PROPERTY: { 4391 case NAMED_PROPERTY: {
4392 __ mov(StoreConvention::NameRegister(), 4392 __ mov(StoreDescriptor::NameRegister(),
4393 Operand(prop->key()->AsLiteral()->value())); 4393 Operand(prop->key()->AsLiteral()->value()));
4394 __ pop(StoreConvention::ReceiverRegister()); 4394 __ pop(StoreDescriptor::ReceiverRegister());
4395 CallStoreIC(expr->CountStoreFeedbackId()); 4395 CallStoreIC(expr->CountStoreFeedbackId());
4396 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4396 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4397 if (expr->is_postfix()) { 4397 if (expr->is_postfix()) {
4398 if (!context()->IsEffect()) { 4398 if (!context()->IsEffect()) {
4399 context()->PlugTOS(); 4399 context()->PlugTOS();
4400 } 4400 }
4401 } else { 4401 } else {
4402 context()->Plug(r0); 4402 context()->Plug(r0);
4403 } 4403 }
4404 break; 4404 break;
4405 } 4405 }
4406 case KEYED_PROPERTY: { 4406 case KEYED_PROPERTY: {
4407 __ Pop(StoreConvention::ReceiverRegister(), 4407 __ Pop(StoreDescriptor::ReceiverRegister(),
4408 StoreConvention::NameRegister()); 4408 StoreDescriptor::NameRegister());
4409 Handle<Code> ic = strict_mode() == SLOPPY 4409 Handle<Code> ic = strict_mode() == SLOPPY
4410 ? isolate()->builtins()->KeyedStoreIC_Initialize() 4410 ? isolate()->builtins()->KeyedStoreIC_Initialize()
4411 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 4411 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
4412 CallIC(ic, expr->CountStoreFeedbackId()); 4412 CallIC(ic, expr->CountStoreFeedbackId());
4413 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4413 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4414 if (expr->is_postfix()) { 4414 if (expr->is_postfix()) {
4415 if (!context()->IsEffect()) { 4415 if (!context()->IsEffect()) {
4416 context()->PlugTOS(); 4416 context()->PlugTOS();
4417 } 4417 }
4418 } else { 4418 } else {
4419 context()->Plug(r0); 4419 context()->Plug(r0);
4420 } 4420 }
4421 break; 4421 break;
4422 } 4422 }
4423 } 4423 }
4424 } 4424 }
4425 4425
4426 4426
4427 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { 4427 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
4428 DCHECK(!context()->IsEffect()); 4428 DCHECK(!context()->IsEffect());
4429 DCHECK(!context()->IsTest()); 4429 DCHECK(!context()->IsTest());
4430 VariableProxy* proxy = expr->AsVariableProxy(); 4430 VariableProxy* proxy = expr->AsVariableProxy();
4431 if (proxy != NULL && proxy->var()->IsUnallocated()) { 4431 if (proxy != NULL && proxy->var()->IsUnallocated()) {
4432 Comment cmnt(masm_, "[ Global variable"); 4432 Comment cmnt(masm_, "[ Global variable");
4433 __ ldr(LoadConvention::ReceiverRegister(), GlobalObjectOperand()); 4433 __ ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
4434 __ mov(LoadConvention::NameRegister(), Operand(proxy->name())); 4434 __ mov(LoadDescriptor::NameRegister(), Operand(proxy->name()));
4435 if (FLAG_vector_ics) { 4435 if (FLAG_vector_ics) {
4436 __ mov(VectorLoadConvention::SlotRegister(), 4436 __ mov(VectorLoadICDescriptor::SlotRegister(),
4437 Operand(Smi::FromInt(proxy->VariableFeedbackSlot()))); 4437 Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
4438 } 4438 }
4439 // Use a regular load, not a contextual load, to avoid a reference 4439 // Use a regular load, not a contextual load, to avoid a reference
4440 // error. 4440 // error.
4441 CallLoadIC(NOT_CONTEXTUAL); 4441 CallLoadIC(NOT_CONTEXTUAL);
4442 PrepareForBailout(expr, TOS_REG); 4442 PrepareForBailout(expr, TOS_REG);
4443 context()->Plug(r0); 4443 context()->Plug(r0);
4444 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { 4444 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
4445 Comment cmnt(masm_, "[ Lookup slot"); 4445 Comment cmnt(masm_, "[ Lookup slot");
4446 Label done, slow; 4446 Label done, slow;
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after
4927 4927
4928 DCHECK(interrupt_address == 4928 DCHECK(interrupt_address ==
4929 isolate->builtins()->OsrAfterStackCheck()->entry()); 4929 isolate->builtins()->OsrAfterStackCheck()->entry());
4930 return OSR_AFTER_STACK_CHECK; 4930 return OSR_AFTER_STACK_CHECK;
4931 } 4931 }
4932 4932
4933 4933
4934 } } // namespace v8::internal 4934 } } // namespace v8::internal
4935 4935
4936 #endif // V8_TARGET_ARCH_ARM 4936 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698