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

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

Issue 486213003: Move register conventions out of the IC classes. (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
« no previous file with comments | « src/arm/debug-arm.cc ('k') | src/arm/lithium-arm.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_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(LoadIC::ReceiverRegister(), GlobalObjectOperand()); 1405 __ ldr(LoadConvention::ReceiverRegister(), GlobalObjectOperand());
1406 __ mov(LoadIC::NameRegister(), Operand(proxy->var()->name())); 1406 __ mov(LoadConvention::NameRegister(), Operand(proxy->var()->name()));
1407 if (FLAG_vector_ics) { 1407 if (FLAG_vector_ics) {
1408 __ mov(LoadIC::SlotRegister(), 1408 __ mov(VectorLoadConvention::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(LoadIC::ReceiverRegister(), GlobalObjectOperand()); 1494 __ ldr(LoadConvention::ReceiverRegister(), GlobalObjectOperand());
1495 __ mov(LoadIC::NameRegister(), Operand(var->name())); 1495 __ mov(LoadConvention::NameRegister(), Operand(var->name()));
1496 if (FLAG_vector_ics) { 1496 if (FLAG_vector_ics) {
1497 __ mov(LoadIC::SlotRegister(), 1497 __ mov(VectorLoadConvention::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(StoreIC::ValueRegister().is(r0)); 1705 DCHECK(StoreConvention::ValueRegister().is(r0));
1706 __ mov(StoreIC::NameRegister(), Operand(key->value())); 1706 __ mov(StoreConvention::NameRegister(), Operand(key->value()));
1707 __ ldr(StoreIC::ReceiverRegister(), MemOperand(sp)); 1707 __ ldr(StoreConvention::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(LoadIC::ReceiverRegister(), MemOperand(sp, 0)); 1886 __ ldr(LoadConvention::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(LoadIC::ReceiverRegister(), MemOperand(sp, 1 * kPointerSize)); 1895 __ ldr(LoadConvention::ReceiverRegister(),
1896 __ ldr(LoadIC::NameRegister(), MemOperand(sp, 0)); 1896 MemOperand(sp, 1 * kPointerSize));
1897 __ ldr(LoadConvention::NameRegister(), MemOperand(sp, 0));
1897 } else { 1898 } else {
1898 VisitForStackValue(property->obj()); 1899 VisitForStackValue(property->obj());
1899 VisitForStackValue(property->key()); 1900 VisitForStackValue(property->key());
1900 } 1901 }
1901 break; 1902 break;
1902 } 1903 }
1903 1904
1904 // For compound assignments we need another deoptimization point after the 1905 // For compound assignments we need another deoptimization point after the
1905 // variable/property load. 1906 // variable/property load.
1906 if (expr->is_compound()) { 1907 if (expr->is_compound()) {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
2025 2026
2026 case Yield::DELEGATING: { 2027 case Yield::DELEGATING: {
2027 VisitForStackValue(expr->generator_object()); 2028 VisitForStackValue(expr->generator_object());
2028 2029
2029 // Initial stack layout is as follows: 2030 // Initial stack layout is as follows:
2030 // [sp + 1 * kPointerSize] iter 2031 // [sp + 1 * kPointerSize] iter
2031 // [sp + 0 * kPointerSize] g 2032 // [sp + 0 * kPointerSize] g
2032 2033
2033 Label l_catch, l_try, l_suspend, l_continuation, l_resume; 2034 Label l_catch, l_try, l_suspend, l_continuation, l_resume;
2034 Label l_next, l_call, l_loop; 2035 Label l_next, l_call, l_loop;
2035 Register load_receiver = LoadIC::ReceiverRegister(); 2036 Register load_receiver = LoadConvention::ReceiverRegister();
2036 Register load_name = LoadIC::NameRegister(); 2037 Register load_name = LoadConvention::NameRegister();
2037 2038
2038 // Initial send value is undefined. 2039 // Initial send value is undefined.
2039 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 2040 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
2040 __ b(&l_next); 2041 __ b(&l_next);
2041 2042
2042 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } 2043 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; }
2043 __ bind(&l_catch); 2044 __ bind(&l_catch);
2044 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); 2045 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
2045 __ LoadRoot(load_name, Heap::kthrow_stringRootIndex); // "throw" 2046 __ LoadRoot(load_name, Heap::kthrow_stringRootIndex); // "throw"
2046 __ 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
2081 2082
2082 __ LoadRoot(load_name, Heap::knext_stringRootIndex); // "next" 2083 __ LoadRoot(load_name, Heap::knext_stringRootIndex); // "next"
2083 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter 2084 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter
2084 __ Push(load_name, r3, r0); // "next", iter, received 2085 __ Push(load_name, r3, r0); // "next", iter, received
2085 2086
2086 // result = receiver[f](arg); 2087 // result = receiver[f](arg);
2087 __ bind(&l_call); 2088 __ bind(&l_call);
2088 __ ldr(load_receiver, MemOperand(sp, kPointerSize)); 2089 __ ldr(load_receiver, MemOperand(sp, kPointerSize));
2089 __ ldr(load_name, MemOperand(sp, 2 * kPointerSize)); 2090 __ ldr(load_name, MemOperand(sp, 2 * kPointerSize));
2090 if (FLAG_vector_ics) { 2091 if (FLAG_vector_ics) {
2091 __ mov(LoadIC::SlotRegister(), 2092 __ mov(VectorLoadConvention::SlotRegister(),
2092 Operand(Smi::FromInt(expr->KeyedLoadFeedbackSlot()))); 2093 Operand(Smi::FromInt(expr->KeyedLoadFeedbackSlot())));
2093 } 2094 }
2094 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2095 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2095 CallIC(ic, TypeFeedbackId::None()); 2096 CallIC(ic, TypeFeedbackId::None());
2096 __ mov(r1, r0); 2097 __ mov(r1, r0);
2097 __ str(r1, MemOperand(sp, 2 * kPointerSize)); 2098 __ str(r1, MemOperand(sp, 2 * kPointerSize));
2098 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); 2099 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD);
2099 __ CallStub(&stub); 2100 __ CallStub(&stub);
2100 2101
2101 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2102 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2102 __ Drop(1); // The function is still on the stack; drop it. 2103 __ Drop(1); // The function is still on the stack; drop it.
2103 2104
2104 // if (!result.done) goto l_try; 2105 // if (!result.done) goto l_try;
2105 __ bind(&l_loop); 2106 __ bind(&l_loop);
2106 __ Move(load_receiver, r0); 2107 __ Move(load_receiver, r0);
2107 2108
2108 __ push(load_receiver); // save result 2109 __ push(load_receiver); // save result
2109 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" 2110 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
2110 if (FLAG_vector_ics) { 2111 if (FLAG_vector_ics) {
2111 __ mov(LoadIC::SlotRegister(), 2112 __ mov(VectorLoadConvention::SlotRegister(),
2112 Operand(Smi::FromInt(expr->DoneFeedbackSlot()))); 2113 Operand(Smi::FromInt(expr->DoneFeedbackSlot())));
2113 } 2114 }
2114 CallLoadIC(NOT_CONTEXTUAL); // r0=result.done 2115 CallLoadIC(NOT_CONTEXTUAL); // r0=result.done
2115 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); 2116 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
2116 CallIC(bool_ic); 2117 CallIC(bool_ic);
2117 __ cmp(r0, Operand(0)); 2118 __ cmp(r0, Operand(0));
2118 __ b(eq, &l_try); 2119 __ b(eq, &l_try);
2119 2120
2120 // result.value 2121 // result.value
2121 __ pop(load_receiver); // result 2122 __ pop(load_receiver); // result
2122 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" 2123 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
2123 if (FLAG_vector_ics) { 2124 if (FLAG_vector_ics) {
2124 __ mov(LoadIC::SlotRegister(), 2125 __ mov(VectorLoadConvention::SlotRegister(),
2125 Operand(Smi::FromInt(expr->ValueFeedbackSlot()))); 2126 Operand(Smi::FromInt(expr->ValueFeedbackSlot())));
2126 } 2127 }
2127 CallLoadIC(NOT_CONTEXTUAL); // r0=result.value 2128 CallLoadIC(NOT_CONTEXTUAL); // r0=result.value
2128 context()->DropAndPlug(2, r0); // drop iter and g 2129 context()->DropAndPlug(2, r0); // drop iter and g
2129 break; 2130 break;
2130 } 2131 }
2131 } 2132 }
2132 } 2133 }
2133 2134
2134 2135
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
2291 // 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
2292 // root set. 2293 // root set.
2293 __ RecordWriteField(r0, JSGeneratorObject::kResultValuePropertyOffset, 2294 __ RecordWriteField(r0, JSGeneratorObject::kResultValuePropertyOffset,
2294 r2, r3, kLRHasBeenSaved, kDontSaveFPRegs); 2295 r2, r3, kLRHasBeenSaved, kDontSaveFPRegs);
2295 } 2296 }
2296 2297
2297 2298
2298 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 2299 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
2299 SetSourcePosition(prop->position()); 2300 SetSourcePosition(prop->position());
2300 Literal* key = prop->key()->AsLiteral(); 2301 Literal* key = prop->key()->AsLiteral();
2301 __ mov(LoadIC::NameRegister(), Operand(key->value())); 2302 __ mov(LoadConvention::NameRegister(), Operand(key->value()));
2302 if (FLAG_vector_ics) { 2303 if (FLAG_vector_ics) {
2303 __ mov(LoadIC::SlotRegister(), 2304 __ mov(VectorLoadConvention::SlotRegister(),
2304 Operand(Smi::FromInt(prop->PropertyFeedbackSlot()))); 2305 Operand(Smi::FromInt(prop->PropertyFeedbackSlot())));
2305 CallLoadIC(NOT_CONTEXTUAL); 2306 CallLoadIC(NOT_CONTEXTUAL);
2306 } else { 2307 } else {
2307 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); 2308 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
2308 } 2309 }
2309 } 2310 }
2310 2311
2311 2312
2312 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 2313 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2313 SetSourcePosition(prop->position()); 2314 SetSourcePosition(prop->position());
2314 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2315 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2315 if (FLAG_vector_ics) { 2316 if (FLAG_vector_ics) {
2316 __ mov(LoadIC::SlotRegister(), 2317 __ mov(VectorLoadConvention::SlotRegister(),
2317 Operand(Smi::FromInt(prop->PropertyFeedbackSlot()))); 2318 Operand(Smi::FromInt(prop->PropertyFeedbackSlot())));
2318 CallIC(ic); 2319 CallIC(ic);
2319 } else { 2320 } else {
2320 CallIC(ic, prop->PropertyFeedbackId()); 2321 CallIC(ic, prop->PropertyFeedbackId());
2321 } 2322 }
2322 } 2323 }
2323 2324
2324 2325
2325 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2326 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
2326 Token::Value op, 2327 Token::Value op,
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
2445 switch (assign_type) { 2446 switch (assign_type) {
2446 case VARIABLE: { 2447 case VARIABLE: {
2447 Variable* var = expr->AsVariableProxy()->var(); 2448 Variable* var = expr->AsVariableProxy()->var();
2448 EffectContext context(this); 2449 EffectContext context(this);
2449 EmitVariableAssignment(var, Token::ASSIGN); 2450 EmitVariableAssignment(var, Token::ASSIGN);
2450 break; 2451 break;
2451 } 2452 }
2452 case NAMED_PROPERTY: { 2453 case NAMED_PROPERTY: {
2453 __ push(r0); // Preserve value. 2454 __ push(r0); // Preserve value.
2454 VisitForAccumulatorValue(prop->obj()); 2455 VisitForAccumulatorValue(prop->obj());
2455 __ Move(StoreIC::ReceiverRegister(), r0); 2456 __ Move(StoreConvention::ReceiverRegister(), r0);
2456 __ pop(StoreIC::ValueRegister()); // Restore value. 2457 __ pop(StoreConvention::ValueRegister()); // Restore value.
2457 __ mov(StoreIC::NameRegister(), 2458 __ mov(StoreConvention::NameRegister(),
2458 Operand(prop->key()->AsLiteral()->value())); 2459 Operand(prop->key()->AsLiteral()->value()));
2459 CallStoreIC(); 2460 CallStoreIC();
2460 break; 2461 break;
2461 } 2462 }
2462 case KEYED_PROPERTY: { 2463 case KEYED_PROPERTY: {
2463 __ push(r0); // Preserve value. 2464 __ push(r0); // Preserve value.
2464 VisitForStackValue(prop->obj()); 2465 VisitForStackValue(prop->obj());
2465 VisitForAccumulatorValue(prop->key()); 2466 VisitForAccumulatorValue(prop->key());
2466 __ Move(KeyedStoreIC::NameRegister(), r0); 2467 __ Move(StoreConvention::NameRegister(), r0);
2467 __ Pop(KeyedStoreIC::ValueRegister(), KeyedStoreIC::ReceiverRegister()); 2468 __ Pop(StoreConvention::ValueRegister(),
2469 StoreConvention::ReceiverRegister());
2468 Handle<Code> ic = strict_mode() == SLOPPY 2470 Handle<Code> ic = strict_mode() == SLOPPY
2469 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2471 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2470 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2472 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2471 CallIC(ic); 2473 CallIC(ic);
2472 break; 2474 break;
2473 } 2475 }
2474 } 2476 }
2475 context()->Plug(r0); 2477 context()->Plug(r0);
2476 } 2478 }
2477 2479
2478 2480
2479 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( 2481 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
2480 Variable* var, MemOperand location) { 2482 Variable* var, MemOperand location) {
2481 __ str(result_register(), location); 2483 __ str(result_register(), location);
2482 if (var->IsContextSlot()) { 2484 if (var->IsContextSlot()) {
2483 // RecordWrite may destroy all its register arguments. 2485 // RecordWrite may destroy all its register arguments.
2484 __ mov(r3, result_register()); 2486 __ mov(r3, result_register());
2485 int offset = Context::SlotOffset(var->index()); 2487 int offset = Context::SlotOffset(var->index());
2486 __ RecordWriteContextSlot( 2488 __ RecordWriteContextSlot(
2487 r1, offset, r3, r2, kLRHasBeenSaved, kDontSaveFPRegs); 2489 r1, offset, r3, r2, kLRHasBeenSaved, kDontSaveFPRegs);
2488 } 2490 }
2489 } 2491 }
2490 2492
2491 2493
2492 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) { 2494 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) {
2493 if (var->IsUnallocated()) { 2495 if (var->IsUnallocated()) {
2494 // Global var, const, or let. 2496 // Global var, const, or let.
2495 __ mov(StoreIC::NameRegister(), Operand(var->name())); 2497 __ mov(StoreConvention::NameRegister(), Operand(var->name()));
2496 __ ldr(StoreIC::ReceiverRegister(), GlobalObjectOperand()); 2498 __ ldr(StoreConvention::ReceiverRegister(), GlobalObjectOperand());
2497 CallStoreIC(); 2499 CallStoreIC();
2498 2500
2499 } else if (op == Token::INIT_CONST_LEGACY) { 2501 } else if (op == Token::INIT_CONST_LEGACY) {
2500 // Const initializers need a write barrier. 2502 // Const initializers need a write barrier.
2501 DCHECK(!var->IsParameter()); // No const parameters. 2503 DCHECK(!var->IsParameter()); // No const parameters.
2502 if (var->IsLookupSlot()) { 2504 if (var->IsLookupSlot()) {
2503 __ push(r0); 2505 __ push(r0);
2504 __ mov(r0, Operand(var->name())); 2506 __ mov(r0, Operand(var->name()));
2505 __ Push(cp, r0); // Context and name. 2507 __ Push(cp, r0); // Context and name.
2506 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); 2508 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2558 2560
2559 2561
2560 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 2562 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
2561 // Assignment to a property, using a named store IC. 2563 // Assignment to a property, using a named store IC.
2562 Property* prop = expr->target()->AsProperty(); 2564 Property* prop = expr->target()->AsProperty();
2563 DCHECK(prop != NULL); 2565 DCHECK(prop != NULL);
2564 DCHECK(prop->key()->IsLiteral()); 2566 DCHECK(prop->key()->IsLiteral());
2565 2567
2566 // Record source code position before IC call. 2568 // Record source code position before IC call.
2567 SetSourcePosition(expr->position()); 2569 SetSourcePosition(expr->position());
2568 __ mov(StoreIC::NameRegister(), Operand(prop->key()->AsLiteral()->value())); 2570 __ mov(StoreConvention::NameRegister(),
2569 __ pop(StoreIC::ReceiverRegister()); 2571 Operand(prop->key()->AsLiteral()->value()));
2572 __ pop(StoreConvention::ReceiverRegister());
2570 CallStoreIC(expr->AssignmentFeedbackId()); 2573 CallStoreIC(expr->AssignmentFeedbackId());
2571 2574
2572 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2575 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2573 context()->Plug(r0); 2576 context()->Plug(r0);
2574 } 2577 }
2575 2578
2576 2579
2577 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2580 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2578 // Assignment to a property, using a keyed store IC. 2581 // Assignment to a property, using a keyed store IC.
2579 2582
2580 // Record source code position before IC call. 2583 // Record source code position before IC call.
2581 SetSourcePosition(expr->position()); 2584 SetSourcePosition(expr->position());
2582 __ Pop(KeyedStoreIC::ReceiverRegister(), KeyedStoreIC::NameRegister()); 2585 __ Pop(StoreConvention::ReceiverRegister(), StoreConvention::NameRegister());
2583 DCHECK(KeyedStoreIC::ValueRegister().is(r0)); 2586 DCHECK(StoreConvention::ValueRegister().is(r0));
2584 2587
2585 Handle<Code> ic = strict_mode() == SLOPPY 2588 Handle<Code> ic = strict_mode() == SLOPPY
2586 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2589 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2587 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2590 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2588 CallIC(ic, expr->AssignmentFeedbackId()); 2591 CallIC(ic, expr->AssignmentFeedbackId());
2589 2592
2590 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2593 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2591 context()->Plug(r0); 2594 context()->Plug(r0);
2592 } 2595 }
2593 2596
2594 2597
2595 void FullCodeGenerator::VisitProperty(Property* expr) { 2598 void FullCodeGenerator::VisitProperty(Property* expr) {
2596 Comment cmnt(masm_, "[ Property"); 2599 Comment cmnt(masm_, "[ Property");
2597 Expression* key = expr->key(); 2600 Expression* key = expr->key();
2598 2601
2599 if (key->IsPropertyName()) { 2602 if (key->IsPropertyName()) {
2600 VisitForAccumulatorValue(expr->obj()); 2603 VisitForAccumulatorValue(expr->obj());
2601 __ Move(LoadIC::ReceiverRegister(), r0); 2604 __ Move(LoadConvention::ReceiverRegister(), r0);
2602 EmitNamedPropertyLoad(expr); 2605 EmitNamedPropertyLoad(expr);
2603 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2606 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
2604 context()->Plug(r0); 2607 context()->Plug(r0);
2605 } else { 2608 } else {
2606 VisitForStackValue(expr->obj()); 2609 VisitForStackValue(expr->obj());
2607 VisitForAccumulatorValue(expr->key()); 2610 VisitForAccumulatorValue(expr->key());
2608 __ Move(LoadIC::NameRegister(), r0); 2611 __ Move(LoadConvention::NameRegister(), r0);
2609 __ pop(LoadIC::ReceiverRegister()); 2612 __ pop(LoadConvention::ReceiverRegister());
2610 EmitKeyedPropertyLoad(expr); 2613 EmitKeyedPropertyLoad(expr);
2611 context()->Plug(r0); 2614 context()->Plug(r0);
2612 } 2615 }
2613 } 2616 }
2614 2617
2615 2618
2616 void FullCodeGenerator::CallIC(Handle<Code> code, 2619 void FullCodeGenerator::CallIC(Handle<Code> code,
2617 TypeFeedbackId ast_id) { 2620 TypeFeedbackId ast_id) {
2618 ic_total_count_++; 2621 ic_total_count_++;
2619 // 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
2636 { StackValueContext context(this); 2639 { StackValueContext context(this);
2637 EmitVariableLoad(callee->AsVariableProxy()); 2640 EmitVariableLoad(callee->AsVariableProxy());
2638 PrepareForBailout(callee, NO_REGISTERS); 2641 PrepareForBailout(callee, NO_REGISTERS);
2639 } 2642 }
2640 // 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
2641 // is a sloppy mode method. 2644 // is a sloppy mode method.
2642 __ Push(isolate()->factory()->undefined_value()); 2645 __ Push(isolate()->factory()->undefined_value());
2643 } else { 2646 } else {
2644 // Load the function from the receiver. 2647 // Load the function from the receiver.
2645 DCHECK(callee->IsProperty()); 2648 DCHECK(callee->IsProperty());
2646 __ ldr(LoadIC::ReceiverRegister(), MemOperand(sp, 0)); 2649 __ ldr(LoadConvention::ReceiverRegister(), MemOperand(sp, 0));
2647 EmitNamedPropertyLoad(callee->AsProperty()); 2650 EmitNamedPropertyLoad(callee->AsProperty());
2648 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2651 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2649 // Push the target function under the receiver. 2652 // Push the target function under the receiver.
2650 __ ldr(ip, MemOperand(sp, 0)); 2653 __ ldr(ip, MemOperand(sp, 0));
2651 __ push(ip); 2654 __ push(ip);
2652 __ str(r0, MemOperand(sp, kPointerSize)); 2655 __ str(r0, MemOperand(sp, kPointerSize));
2653 } 2656 }
2654 2657
2655 EmitCall(expr, call_type); 2658 EmitCall(expr, call_type);
2656 } 2659 }
2657 2660
2658 2661
2659 // Code common for calls using the IC. 2662 // Code common for calls using the IC.
2660 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, 2663 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
2661 Expression* key) { 2664 Expression* key) {
2662 // Load the key. 2665 // Load the key.
2663 VisitForAccumulatorValue(key); 2666 VisitForAccumulatorValue(key);
2664 2667
2665 Expression* callee = expr->expression(); 2668 Expression* callee = expr->expression();
2666 2669
2667 // Load the function from the receiver. 2670 // Load the function from the receiver.
2668 DCHECK(callee->IsProperty()); 2671 DCHECK(callee->IsProperty());
2669 __ ldr(LoadIC::ReceiverRegister(), MemOperand(sp, 0)); 2672 __ ldr(LoadConvention::ReceiverRegister(), MemOperand(sp, 0));
2670 __ Move(LoadIC::NameRegister(), r0); 2673 __ Move(LoadConvention::NameRegister(), r0);
2671 EmitKeyedPropertyLoad(callee->AsProperty()); 2674 EmitKeyedPropertyLoad(callee->AsProperty());
2672 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); 2675 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
2673 2676
2674 // Push the target function under the receiver. 2677 // Push the target function under the receiver.
2675 __ ldr(ip, MemOperand(sp, 0)); 2678 __ ldr(ip, MemOperand(sp, 0));
2676 __ push(ip); 2679 __ push(ip);
2677 __ str(r0, MemOperand(sp, kPointerSize)); 2680 __ str(r0, MemOperand(sp, kPointerSize));
2678 2681
2679 EmitCall(expr, CallIC::METHOD); 2682 EmitCall(expr, CallIC::METHOD);
2680 } 2683 }
(...skipping 1392 matching lines...) Expand 10 before | Expand all | Expand 10 after
4073 EmitInlineRuntimeCall(expr); 4076 EmitInlineRuntimeCall(expr);
4074 return; 4077 return;
4075 } 4078 }
4076 4079
4077 Comment cmnt(masm_, "[ CallRuntime"); 4080 Comment cmnt(masm_, "[ CallRuntime");
4078 ZoneList<Expression*>* args = expr->arguments(); 4081 ZoneList<Expression*>* args = expr->arguments();
4079 int arg_count = args->length(); 4082 int arg_count = args->length();
4080 4083
4081 if (expr->is_jsruntime()) { 4084 if (expr->is_jsruntime()) {
4082 // Push the builtins object as the receiver. 4085 // Push the builtins object as the receiver.
4083 Register receiver = LoadIC::ReceiverRegister(); 4086 Register receiver = LoadConvention::ReceiverRegister();
4084 __ ldr(receiver, GlobalObjectOperand()); 4087 __ ldr(receiver, GlobalObjectOperand());
4085 __ ldr(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset)); 4088 __ ldr(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset));
4086 __ push(receiver); 4089 __ push(receiver);
4087 4090
4088 // Load the function from the receiver. 4091 // Load the function from the receiver.
4089 __ mov(LoadIC::NameRegister(), Operand(expr->name())); 4092 __ mov(LoadConvention::NameRegister(), Operand(expr->name()));
4090 if (FLAG_vector_ics) { 4093 if (FLAG_vector_ics) {
4091 __ mov(LoadIC::SlotRegister(), 4094 __ mov(VectorLoadConvention::SlotRegister(),
4092 Operand(Smi::FromInt(expr->CallRuntimeFeedbackSlot()))); 4095 Operand(Smi::FromInt(expr->CallRuntimeFeedbackSlot())));
4093 CallLoadIC(NOT_CONTEXTUAL); 4096 CallLoadIC(NOT_CONTEXTUAL);
4094 } else { 4097 } else {
4095 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); 4098 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
4096 } 4099 }
4097 4100
4098 // Push the target function under the receiver. 4101 // Push the target function under the receiver.
4099 __ ldr(ip, MemOperand(sp, 0)); 4102 __ ldr(ip, MemOperand(sp, 0));
4100 __ push(ip); 4103 __ push(ip);
4101 __ str(r0, MemOperand(sp, kPointerSize)); 4104 __ str(r0, MemOperand(sp, kPointerSize));
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
4264 EmitVariableLoad(expr->expression()->AsVariableProxy()); 4267 EmitVariableLoad(expr->expression()->AsVariableProxy());
4265 } else { 4268 } else {
4266 // Reserve space for result of postfix operation. 4269 // Reserve space for result of postfix operation.
4267 if (expr->is_postfix() && !context()->IsEffect()) { 4270 if (expr->is_postfix() && !context()->IsEffect()) {
4268 __ mov(ip, Operand(Smi::FromInt(0))); 4271 __ mov(ip, Operand(Smi::FromInt(0)));
4269 __ push(ip); 4272 __ push(ip);
4270 } 4273 }
4271 if (assign_type == NAMED_PROPERTY) { 4274 if (assign_type == NAMED_PROPERTY) {
4272 // Put the object both on the stack and in the register. 4275 // Put the object both on the stack and in the register.
4273 VisitForStackValue(prop->obj()); 4276 VisitForStackValue(prop->obj());
4274 __ ldr(LoadIC::ReceiverRegister(), MemOperand(sp, 0)); 4277 __ ldr(LoadConvention::ReceiverRegister(), MemOperand(sp, 0));
4275 EmitNamedPropertyLoad(prop); 4278 EmitNamedPropertyLoad(prop);
4276 } else { 4279 } else {
4277 VisitForStackValue(prop->obj()); 4280 VisitForStackValue(prop->obj());
4278 VisitForStackValue(prop->key()); 4281 VisitForStackValue(prop->key());
4279 __ ldr(LoadIC::ReceiverRegister(), MemOperand(sp, 1 * kPointerSize)); 4282 __ ldr(LoadConvention::ReceiverRegister(),
4280 __ ldr(LoadIC::NameRegister(), MemOperand(sp, 0)); 4283 MemOperand(sp, 1 * kPointerSize));
4284 __ ldr(LoadConvention::NameRegister(), MemOperand(sp, 0));
4281 EmitKeyedPropertyLoad(prop); 4285 EmitKeyedPropertyLoad(prop);
4282 } 4286 }
4283 } 4287 }
4284 4288
4285 // We need a second deoptimization point after loading the value 4289 // We need a second deoptimization point after loading the value
4286 // in case evaluating the property load my have a side effect. 4290 // in case evaluating the property load my have a side effect.
4287 if (assign_type == VARIABLE) { 4291 if (assign_type == VARIABLE) {
4288 PrepareForBailout(expr->expression(), TOS_REG); 4292 PrepareForBailout(expr->expression(), TOS_REG);
4289 } else { 4293 } else {
4290 PrepareForBailoutForId(prop->LoadId(), TOS_REG); 4294 PrepareForBailoutForId(prop->LoadId(), TOS_REG);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
4378 context()->PlugTOS(); 4382 context()->PlugTOS();
4379 } 4383 }
4380 } else { 4384 } else {
4381 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 4385 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
4382 Token::ASSIGN); 4386 Token::ASSIGN);
4383 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4387 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4384 context()->Plug(r0); 4388 context()->Plug(r0);
4385 } 4389 }
4386 break; 4390 break;
4387 case NAMED_PROPERTY: { 4391 case NAMED_PROPERTY: {
4388 __ mov(StoreIC::NameRegister(), 4392 __ mov(StoreConvention::NameRegister(),
4389 Operand(prop->key()->AsLiteral()->value())); 4393 Operand(prop->key()->AsLiteral()->value()));
4390 __ pop(StoreIC::ReceiverRegister()); 4394 __ pop(StoreConvention::ReceiverRegister());
4391 CallStoreIC(expr->CountStoreFeedbackId()); 4395 CallStoreIC(expr->CountStoreFeedbackId());
4392 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4396 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4393 if (expr->is_postfix()) { 4397 if (expr->is_postfix()) {
4394 if (!context()->IsEffect()) { 4398 if (!context()->IsEffect()) {
4395 context()->PlugTOS(); 4399 context()->PlugTOS();
4396 } 4400 }
4397 } else { 4401 } else {
4398 context()->Plug(r0); 4402 context()->Plug(r0);
4399 } 4403 }
4400 break; 4404 break;
4401 } 4405 }
4402 case KEYED_PROPERTY: { 4406 case KEYED_PROPERTY: {
4403 __ Pop(KeyedStoreIC::ReceiverRegister(), KeyedStoreIC::NameRegister()); 4407 __ Pop(StoreConvention::ReceiverRegister(),
4408 StoreConvention::NameRegister());
4404 Handle<Code> ic = strict_mode() == SLOPPY 4409 Handle<Code> ic = strict_mode() == SLOPPY
4405 ? isolate()->builtins()->KeyedStoreIC_Initialize() 4410 ? isolate()->builtins()->KeyedStoreIC_Initialize()
4406 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 4411 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
4407 CallIC(ic, expr->CountStoreFeedbackId()); 4412 CallIC(ic, expr->CountStoreFeedbackId());
4408 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4413 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4409 if (expr->is_postfix()) { 4414 if (expr->is_postfix()) {
4410 if (!context()->IsEffect()) { 4415 if (!context()->IsEffect()) {
4411 context()->PlugTOS(); 4416 context()->PlugTOS();
4412 } 4417 }
4413 } else { 4418 } else {
4414 context()->Plug(r0); 4419 context()->Plug(r0);
4415 } 4420 }
4416 break; 4421 break;
4417 } 4422 }
4418 } 4423 }
4419 } 4424 }
4420 4425
4421 4426
4422 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { 4427 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
4423 DCHECK(!context()->IsEffect()); 4428 DCHECK(!context()->IsEffect());
4424 DCHECK(!context()->IsTest()); 4429 DCHECK(!context()->IsTest());
4425 VariableProxy* proxy = expr->AsVariableProxy(); 4430 VariableProxy* proxy = expr->AsVariableProxy();
4426 if (proxy != NULL && proxy->var()->IsUnallocated()) { 4431 if (proxy != NULL && proxy->var()->IsUnallocated()) {
4427 Comment cmnt(masm_, "[ Global variable"); 4432 Comment cmnt(masm_, "[ Global variable");
4428 __ ldr(LoadIC::ReceiverRegister(), GlobalObjectOperand()); 4433 __ ldr(LoadConvention::ReceiverRegister(), GlobalObjectOperand());
4429 __ mov(LoadIC::NameRegister(), Operand(proxy->name())); 4434 __ mov(LoadConvention::NameRegister(), Operand(proxy->name()));
4430 if (FLAG_vector_ics) { 4435 if (FLAG_vector_ics) {
4431 __ mov(LoadIC::SlotRegister(), 4436 __ mov(VectorLoadConvention::SlotRegister(),
4432 Operand(Smi::FromInt(proxy->VariableFeedbackSlot()))); 4437 Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
4433 } 4438 }
4434 // 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
4435 // error. 4440 // error.
4436 CallLoadIC(NOT_CONTEXTUAL); 4441 CallLoadIC(NOT_CONTEXTUAL);
4437 PrepareForBailout(expr, TOS_REG); 4442 PrepareForBailout(expr, TOS_REG);
4438 context()->Plug(r0); 4443 context()->Plug(r0);
4439 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { 4444 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
4440 Comment cmnt(masm_, "[ Lookup slot"); 4445 Comment cmnt(masm_, "[ Lookup slot");
4441 Label done, slow; 4446 Label done, slow;
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after
4922 4927
4923 DCHECK(interrupt_address == 4928 DCHECK(interrupt_address ==
4924 isolate->builtins()->OsrAfterStackCheck()->entry()); 4929 isolate->builtins()->OsrAfterStackCheck()->entry());
4925 return OSR_AFTER_STACK_CHECK; 4930 return OSR_AFTER_STACK_CHECK;
4926 } 4931 }
4927 4932
4928 4933
4929 } } // namespace v8::internal 4934 } } // namespace v8::internal
4930 4935
4931 #endif // V8_TARGET_ARCH_ARM 4936 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/debug-arm.cc ('k') | src/arm/lithium-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698