OLD | NEW |
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 1371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1382 // Check that extension is NULL. | 1382 // Check that extension is NULL. |
1383 __ ldr(temp, ContextOperand(next, Context::EXTENSION_INDEX)); | 1383 __ ldr(temp, ContextOperand(next, Context::EXTENSION_INDEX)); |
1384 __ tst(temp, temp); | 1384 __ tst(temp, temp); |
1385 __ b(ne, slow); | 1385 __ b(ne, slow); |
1386 // Load next context in chain. | 1386 // Load next context in chain. |
1387 __ ldr(next, ContextOperand(next, Context::PREVIOUS_INDEX)); | 1387 __ ldr(next, ContextOperand(next, Context::PREVIOUS_INDEX)); |
1388 __ b(&loop); | 1388 __ b(&loop); |
1389 __ bind(&fast); | 1389 __ bind(&fast); |
1390 } | 1390 } |
1391 | 1391 |
1392 __ ldr(r0, GlobalObjectOperand()); | 1392 __ ldr(LoadIC::ReceiverRegister(), GlobalObjectOperand()); |
1393 __ mov(r2, Operand(var->name())); | 1393 __ mov(LoadIC::NameRegister(), Operand(var->name())); |
1394 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) | 1394 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) |
1395 ? NOT_CONTEXTUAL | 1395 ? NOT_CONTEXTUAL |
1396 : CONTEXTUAL; | 1396 : CONTEXTUAL; |
1397 CallLoadIC(mode); | 1397 CallLoadIC(mode); |
1398 } | 1398 } |
1399 | 1399 |
1400 | 1400 |
1401 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1401 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
1402 Label* slow) { | 1402 Label* slow) { |
1403 ASSERT(var->IsContextSlot()); | 1403 ASSERT(var->IsContextSlot()); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1465 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { | 1465 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
1466 // Record position before possible IC call. | 1466 // Record position before possible IC call. |
1467 SetSourcePosition(proxy->position()); | 1467 SetSourcePosition(proxy->position()); |
1468 Variable* var = proxy->var(); | 1468 Variable* var = proxy->var(); |
1469 | 1469 |
1470 // Three cases: global variables, lookup variables, and all other types of | 1470 // Three cases: global variables, lookup variables, and all other types of |
1471 // variables. | 1471 // variables. |
1472 switch (var->location()) { | 1472 switch (var->location()) { |
1473 case Variable::UNALLOCATED: { | 1473 case Variable::UNALLOCATED: { |
1474 Comment cmnt(masm_, "[ Global variable"); | 1474 Comment cmnt(masm_, "[ Global variable"); |
1475 // Use inline caching. Variable name is passed in r2 and the global | 1475 __ ldr(LoadIC::ReceiverRegister(), GlobalObjectOperand()); |
1476 // object (receiver) in r0. | 1476 __ mov(LoadIC::NameRegister(), Operand(var->name())); |
1477 __ ldr(r0, GlobalObjectOperand()); | |
1478 __ mov(r2, Operand(var->name())); | |
1479 CallLoadIC(CONTEXTUAL); | 1477 CallLoadIC(CONTEXTUAL); |
1480 context()->Plug(r0); | 1478 context()->Plug(r0); |
1481 break; | 1479 break; |
1482 } | 1480 } |
1483 | 1481 |
1484 case Variable::PARAMETER: | 1482 case Variable::PARAMETER: |
1485 case Variable::LOCAL: | 1483 case Variable::LOCAL: |
1486 case Variable::CONTEXT: { | 1484 case Variable::CONTEXT: { |
1487 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" | 1485 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" |
1488 : "[ Stack variable"); | 1486 : "[ Stack variable"); |
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2046 kLRHasBeenSaved, kDontSaveFPRegs); | 2044 kLRHasBeenSaved, kDontSaveFPRegs); |
2047 __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1); | 2045 __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1); |
2048 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2046 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2049 __ pop(r0); // result | 2047 __ pop(r0); // result |
2050 EmitReturnSequence(); | 2048 EmitReturnSequence(); |
2051 __ bind(&l_resume); // received in r0 | 2049 __ bind(&l_resume); // received in r0 |
2052 __ PopTryHandler(); | 2050 __ PopTryHandler(); |
2053 | 2051 |
2054 // receiver = iter; f = 'next'; arg = received; | 2052 // receiver = iter; f = 'next'; arg = received; |
2055 __ bind(&l_next); | 2053 __ bind(&l_next); |
| 2054 Register keyedload_receiver = KeyedLoadIC::ReceiverRegister(); |
| 2055 Register keyedload_name = KeyedLoadIC::NameRegister(); |
| 2056 ASSERT(keyedload_receiver.is(r1)); |
| 2057 ASSERT(keyedload_name.is(r0)); |
| 2058 |
2056 __ LoadRoot(r2, Heap::knext_stringRootIndex); // "next" | 2059 __ LoadRoot(r2, Heap::knext_stringRootIndex); // "next" |
2057 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter | 2060 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter |
2058 __ Push(r2, r3, r0); // "next", iter, received | 2061 __ Push(r2, r3, r0); // "next", iter, received |
2059 | 2062 |
2060 // result = receiver[f](arg); | 2063 // result = receiver[f](arg); |
2061 __ bind(&l_call); | 2064 __ bind(&l_call); |
2062 __ ldr(r1, MemOperand(sp, kPointerSize)); | 2065 __ ldr(keyedload_receiver, MemOperand(sp, kPointerSize)); |
2063 __ ldr(r0, MemOperand(sp, 2 * kPointerSize)); | 2066 __ ldr(keyedload_name, MemOperand(sp, 2 * kPointerSize)); |
2064 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2067 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
2065 CallIC(ic, TypeFeedbackId::None()); | 2068 CallIC(ic, TypeFeedbackId::None()); |
2066 __ mov(r1, r0); | 2069 __ mov(r1, r0); |
2067 __ str(r1, MemOperand(sp, 2 * kPointerSize)); | 2070 __ str(r1, MemOperand(sp, 2 * kPointerSize)); |
2068 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); | 2071 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); |
2069 __ CallStub(&stub); | 2072 __ CallStub(&stub); |
2070 | 2073 |
2071 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2074 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2072 __ Drop(1); // The function is still on the stack; drop it. | 2075 __ Drop(1); // The function is still on the stack; drop it. |
2073 | 2076 |
2074 // if (!result.done) goto l_try; | 2077 // if (!result.done) goto l_try; |
2075 __ bind(&l_loop); | 2078 __ bind(&l_loop); |
2076 __ push(r0); // save result | 2079 Register load_receiver = LoadIC::ReceiverRegister(); |
2077 __ LoadRoot(r2, Heap::kdone_stringRootIndex); // "done" | 2080 Register load_name = LoadIC::NameRegister(); |
2078 CallLoadIC(NOT_CONTEXTUAL); // result.done in r0 | 2081 ASSERT(load_receiver.is(r0)); |
| 2082 ASSERT(load_name.is(r2)); |
| 2083 |
| 2084 __ push(load_receiver); // save result |
| 2085 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" |
| 2086 CallLoadIC(NOT_CONTEXTUAL); // r0=result.done |
2079 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); | 2087 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); |
2080 CallIC(bool_ic); | 2088 CallIC(bool_ic); |
2081 __ cmp(r0, Operand(0)); | 2089 __ cmp(r0, Operand(0)); |
2082 __ b(eq, &l_try); | 2090 __ b(eq, &l_try); |
2083 | 2091 |
2084 // result.value | 2092 // result.value |
2085 __ pop(r0); // result | 2093 __ pop(load_receiver); // result |
2086 __ LoadRoot(r2, Heap::kvalue_stringRootIndex); // "value" | 2094 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" |
2087 CallLoadIC(NOT_CONTEXTUAL); // result.value in r0 | 2095 CallLoadIC(NOT_CONTEXTUAL); // r0=result.value |
2088 context()->DropAndPlug(2, r0); // drop iter and g | 2096 context()->DropAndPlug(2, r0); // drop iter and g |
2089 break; | 2097 break; |
2090 } | 2098 } |
2091 } | 2099 } |
2092 } | 2100 } |
2093 | 2101 |
2094 | 2102 |
2095 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 2103 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
2096 Expression *value, | 2104 Expression *value, |
2097 JSGeneratorObject::ResumeMode resume_mode) { | 2105 JSGeneratorObject::ResumeMode resume_mode) { |
2098 // The value stays in r0, and is ultimately read by the resumed generator, as | 2106 // The value stays in r0, and is ultimately read by the resumed generator, as |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2251 // Only the value field needs a write barrier, as the other values are in the | 2259 // Only the value field needs a write barrier, as the other values are in the |
2252 // root set. | 2260 // root set. |
2253 __ RecordWriteField(r0, JSGeneratorObject::kResultValuePropertyOffset, | 2261 __ RecordWriteField(r0, JSGeneratorObject::kResultValuePropertyOffset, |
2254 r2, r3, kLRHasBeenSaved, kDontSaveFPRegs); | 2262 r2, r3, kLRHasBeenSaved, kDontSaveFPRegs); |
2255 } | 2263 } |
2256 | 2264 |
2257 | 2265 |
2258 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2266 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
2259 SetSourcePosition(prop->position()); | 2267 SetSourcePosition(prop->position()); |
2260 Literal* key = prop->key()->AsLiteral(); | 2268 Literal* key = prop->key()->AsLiteral(); |
2261 __ mov(r2, Operand(key->value())); | 2269 __ mov(LoadIC::NameRegister(), Operand(key->value())); |
2262 // Call load IC. It has arguments receiver and property name r0 and r2. | 2270 // Call load IC. It has register arguments receiver and property. |
2263 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); | 2271 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
2264 } | 2272 } |
2265 | 2273 |
2266 | 2274 |
2267 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2275 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
2268 SetSourcePosition(prop->position()); | 2276 SetSourcePosition(prop->position()); |
2269 // Call keyed load IC. It has arguments key and receiver in r0 and r1. | 2277 // Call keyed load IC. It has register arguments receiver and key. |
2270 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2278 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
2271 CallIC(ic, prop->PropertyFeedbackId()); | 2279 CallIC(ic, prop->PropertyFeedbackId()); |
2272 } | 2280 } |
2273 | 2281 |
2274 | 2282 |
2275 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2283 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
2276 Token::Value op, | 2284 Token::Value op, |
2277 OverwriteMode mode, | 2285 OverwriteMode mode, |
2278 Expression* left_expr, | 2286 Expression* left_expr, |
2279 Expression* right_expr) { | 2287 Expression* right_expr) { |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2548 context()->Plug(r0); | 2556 context()->Plug(r0); |
2549 } | 2557 } |
2550 | 2558 |
2551 | 2559 |
2552 void FullCodeGenerator::VisitProperty(Property* expr) { | 2560 void FullCodeGenerator::VisitProperty(Property* expr) { |
2553 Comment cmnt(masm_, "[ Property"); | 2561 Comment cmnt(masm_, "[ Property"); |
2554 Expression* key = expr->key(); | 2562 Expression* key = expr->key(); |
2555 | 2563 |
2556 if (key->IsPropertyName()) { | 2564 if (key->IsPropertyName()) { |
2557 VisitForAccumulatorValue(expr->obj()); | 2565 VisitForAccumulatorValue(expr->obj()); |
| 2566 ASSERT(r0.is(LoadIC::ReceiverRegister())); |
2558 EmitNamedPropertyLoad(expr); | 2567 EmitNamedPropertyLoad(expr); |
2559 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2568 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
2560 context()->Plug(r0); | 2569 context()->Plug(r0); |
2561 } else { | 2570 } else { |
2562 VisitForStackValue(expr->obj()); | 2571 VisitForStackValue(expr->obj()); |
2563 VisitForAccumulatorValue(expr->key()); | 2572 VisitForAccumulatorValue(expr->key()); |
2564 __ pop(r1); | 2573 ASSERT(r0.is(KeyedLoadIC::NameRegister())); |
| 2574 __ pop(KeyedLoadIC::ReceiverRegister()); |
2565 EmitKeyedPropertyLoad(expr); | 2575 EmitKeyedPropertyLoad(expr); |
2566 context()->Plug(r0); | 2576 context()->Plug(r0); |
2567 } | 2577 } |
2568 } | 2578 } |
2569 | 2579 |
2570 | 2580 |
2571 void FullCodeGenerator::CallIC(Handle<Code> code, | 2581 void FullCodeGenerator::CallIC(Handle<Code> code, |
2572 TypeFeedbackId ast_id) { | 2582 TypeFeedbackId ast_id) { |
2573 ic_total_count_++; | 2583 ic_total_count_++; |
2574 // All calls must have a predictable size in full-codegen code to ensure that | 2584 // All calls must have a predictable size in full-codegen code to ensure that |
(...skipping 16 matching lines...) Expand all Loading... |
2591 { StackValueContext context(this); | 2601 { StackValueContext context(this); |
2592 EmitVariableLoad(callee->AsVariableProxy()); | 2602 EmitVariableLoad(callee->AsVariableProxy()); |
2593 PrepareForBailout(callee, NO_REGISTERS); | 2603 PrepareForBailout(callee, NO_REGISTERS); |
2594 } | 2604 } |
2595 // Push undefined as receiver. This is patched in the method prologue if it | 2605 // Push undefined as receiver. This is patched in the method prologue if it |
2596 // is a sloppy mode method. | 2606 // is a sloppy mode method. |
2597 __ Push(isolate()->factory()->undefined_value()); | 2607 __ Push(isolate()->factory()->undefined_value()); |
2598 } else { | 2608 } else { |
2599 // Load the function from the receiver. | 2609 // Load the function from the receiver. |
2600 ASSERT(callee->IsProperty()); | 2610 ASSERT(callee->IsProperty()); |
2601 __ ldr(r0, MemOperand(sp, 0)); | 2611 __ ldr(LoadIC::ReceiverRegister(), MemOperand(sp, 0)); |
2602 EmitNamedPropertyLoad(callee->AsProperty()); | 2612 EmitNamedPropertyLoad(callee->AsProperty()); |
2603 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2613 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2604 // Push the target function under the receiver. | 2614 // Push the target function under the receiver. |
2605 __ ldr(ip, MemOperand(sp, 0)); | 2615 __ ldr(ip, MemOperand(sp, 0)); |
2606 __ push(ip); | 2616 __ push(ip); |
2607 __ str(r0, MemOperand(sp, kPointerSize)); | 2617 __ str(r0, MemOperand(sp, kPointerSize)); |
2608 } | 2618 } |
2609 | 2619 |
2610 EmitCall(expr, call_type); | 2620 EmitCall(expr, call_type); |
2611 } | 2621 } |
2612 | 2622 |
2613 | 2623 |
2614 // Code common for calls using the IC. | 2624 // Code common for calls using the IC. |
2615 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 2625 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
2616 Expression* key) { | 2626 Expression* key) { |
2617 // Load the key. | 2627 // Load the key. |
2618 VisitForAccumulatorValue(key); | 2628 VisitForAccumulatorValue(key); |
| 2629 ASSERT(r0.is(KeyedLoadIC::NameRegister())); |
2619 | 2630 |
2620 Expression* callee = expr->expression(); | 2631 Expression* callee = expr->expression(); |
2621 | 2632 |
2622 // Load the function from the receiver. | 2633 // Load the function from the receiver. |
2623 ASSERT(callee->IsProperty()); | 2634 ASSERT(callee->IsProperty()); |
2624 __ ldr(r1, MemOperand(sp, 0)); | 2635 __ ldr(KeyedLoadIC::ReceiverRegister(), MemOperand(sp, 0)); |
2625 EmitKeyedPropertyLoad(callee->AsProperty()); | 2636 EmitKeyedPropertyLoad(callee->AsProperty()); |
2626 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2637 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2627 | 2638 |
2628 // Push the target function under the receiver. | 2639 // Push the target function under the receiver. |
2629 __ ldr(ip, MemOperand(sp, 0)); | 2640 __ ldr(ip, MemOperand(sp, 0)); |
2630 __ push(ip); | 2641 __ push(ip); |
2631 __ str(r0, MemOperand(sp, kPointerSize)); | 2642 __ str(r0, MemOperand(sp, kPointerSize)); |
2632 | 2643 |
2633 EmitCall(expr, CallIC::METHOD); | 2644 EmitCall(expr, CallIC::METHOD); |
2634 } | 2645 } |
(...skipping 1397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4032 ZoneList<Expression*>* args = expr->arguments(); | 4043 ZoneList<Expression*>* args = expr->arguments(); |
4033 int arg_count = args->length(); | 4044 int arg_count = args->length(); |
4034 | 4045 |
4035 if (expr->is_jsruntime()) { | 4046 if (expr->is_jsruntime()) { |
4036 // Push the builtins object as the receiver. | 4047 // Push the builtins object as the receiver. |
4037 __ ldr(r0, GlobalObjectOperand()); | 4048 __ ldr(r0, GlobalObjectOperand()); |
4038 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kBuiltinsOffset)); | 4049 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kBuiltinsOffset)); |
4039 __ push(r0); | 4050 __ push(r0); |
4040 | 4051 |
4041 // Load the function from the receiver. | 4052 // Load the function from the receiver. |
4042 __ mov(r2, Operand(expr->name())); | 4053 ASSERT(r0.is(LoadIC::ReceiverRegister())); |
| 4054 __ mov(LoadIC::NameRegister(), Operand(expr->name())); |
4043 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); | 4055 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); |
4044 | 4056 |
4045 // Push the target function under the receiver. | 4057 // Push the target function under the receiver. |
4046 __ ldr(ip, MemOperand(sp, 0)); | 4058 __ ldr(ip, MemOperand(sp, 0)); |
4047 __ push(ip); | 4059 __ push(ip); |
4048 __ str(r0, MemOperand(sp, kPointerSize)); | 4060 __ str(r0, MemOperand(sp, kPointerSize)); |
4049 | 4061 |
4050 // Push the arguments ("left-to-right"). | 4062 // Push the arguments ("left-to-right"). |
4051 int arg_count = args->length(); | 4063 int arg_count = args->length(); |
4052 for (int i = 0; i < arg_count; i++) { | 4064 for (int i = 0; i < arg_count; i++) { |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4211 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4223 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
4212 } else { | 4224 } else { |
4213 // Reserve space for result of postfix operation. | 4225 // Reserve space for result of postfix operation. |
4214 if (expr->is_postfix() && !context()->IsEffect()) { | 4226 if (expr->is_postfix() && !context()->IsEffect()) { |
4215 __ mov(ip, Operand(Smi::FromInt(0))); | 4227 __ mov(ip, Operand(Smi::FromInt(0))); |
4216 __ push(ip); | 4228 __ push(ip); |
4217 } | 4229 } |
4218 if (assign_type == NAMED_PROPERTY) { | 4230 if (assign_type == NAMED_PROPERTY) { |
4219 // Put the object both on the stack and in the accumulator. | 4231 // Put the object both on the stack and in the accumulator. |
4220 VisitForAccumulatorValue(prop->obj()); | 4232 VisitForAccumulatorValue(prop->obj()); |
4221 __ push(r0); | 4233 ASSERT(r0.is(LoadIC::ReceiverRegister())); |
| 4234 __ push(LoadIC::ReceiverRegister()); |
4222 EmitNamedPropertyLoad(prop); | 4235 EmitNamedPropertyLoad(prop); |
4223 } else { | 4236 } else { |
4224 VisitForStackValue(prop->obj()); | 4237 VisitForStackValue(prop->obj()); |
4225 VisitForAccumulatorValue(prop->key()); | 4238 VisitForAccumulatorValue(prop->key()); |
4226 __ ldr(r1, MemOperand(sp, 0)); | 4239 ASSERT(r0.is(KeyedLoadIC::NameRegister())); |
4227 __ push(r0); | 4240 __ ldr(KeyedLoadIC::ReceiverRegister(), MemOperand(sp, 0)); |
| 4241 __ push(KeyedLoadIC::NameRegister()); |
4228 EmitKeyedPropertyLoad(prop); | 4242 EmitKeyedPropertyLoad(prop); |
4229 } | 4243 } |
4230 } | 4244 } |
4231 | 4245 |
4232 // We need a second deoptimization point after loading the value | 4246 // We need a second deoptimization point after loading the value |
4233 // in case evaluating the property load my have a side effect. | 4247 // in case evaluating the property load my have a side effect. |
4234 if (assign_type == VARIABLE) { | 4248 if (assign_type == VARIABLE) { |
4235 PrepareForBailout(expr->expression(), TOS_REG); | 4249 PrepareForBailout(expr->expression(), TOS_REG); |
4236 } else { | 4250 } else { |
4237 PrepareForBailoutForId(prop->LoadId(), TOS_REG); | 4251 PrepareForBailoutForId(prop->LoadId(), TOS_REG); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4364 } | 4378 } |
4365 } | 4379 } |
4366 | 4380 |
4367 | 4381 |
4368 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 4382 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
4369 ASSERT(!context()->IsEffect()); | 4383 ASSERT(!context()->IsEffect()); |
4370 ASSERT(!context()->IsTest()); | 4384 ASSERT(!context()->IsTest()); |
4371 VariableProxy* proxy = expr->AsVariableProxy(); | 4385 VariableProxy* proxy = expr->AsVariableProxy(); |
4372 if (proxy != NULL && proxy->var()->IsUnallocated()) { | 4386 if (proxy != NULL && proxy->var()->IsUnallocated()) { |
4373 Comment cmnt(masm_, "[ Global variable"); | 4387 Comment cmnt(masm_, "[ Global variable"); |
4374 __ ldr(r0, GlobalObjectOperand()); | 4388 __ ldr(LoadIC::ReceiverRegister(), GlobalObjectOperand()); |
4375 __ mov(r2, Operand(proxy->name())); | 4389 __ mov(LoadIC::NameRegister(), Operand(proxy->name())); |
4376 // Use a regular load, not a contextual load, to avoid a reference | 4390 // Use a regular load, not a contextual load, to avoid a reference |
4377 // error. | 4391 // error. |
4378 CallLoadIC(NOT_CONTEXTUAL); | 4392 CallLoadIC(NOT_CONTEXTUAL); |
4379 PrepareForBailout(expr, TOS_REG); | 4393 PrepareForBailout(expr, TOS_REG); |
4380 context()->Plug(r0); | 4394 context()->Plug(r0); |
4381 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 4395 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
4382 Comment cmnt(masm_, "[ Lookup slot"); | 4396 Comment cmnt(masm_, "[ Lookup slot"); |
4383 Label done, slow; | 4397 Label done, slow; |
4384 | 4398 |
4385 // Generate code for loading from variables potentially shadowed | 4399 // Generate code for loading from variables potentially shadowed |
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4821 | 4835 |
4822 ASSERT(interrupt_address == | 4836 ASSERT(interrupt_address == |
4823 isolate->builtins()->OsrAfterStackCheck()->entry()); | 4837 isolate->builtins()->OsrAfterStackCheck()->entry()); |
4824 return OSR_AFTER_STACK_CHECK; | 4838 return OSR_AFTER_STACK_CHECK; |
4825 } | 4839 } |
4826 | 4840 |
4827 | 4841 |
4828 } } // namespace v8::internal | 4842 } } // namespace v8::internal |
4829 | 4843 |
4830 #endif // V8_TARGET_ARCH_ARM | 4844 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |