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_X87 | 7 #if V8_TARGET_ARCH_X87 |
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 1316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1327 __ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0)); | 1327 __ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0)); |
1328 __ j(not_equal, slow); | 1328 __ j(not_equal, slow); |
1329 // Load next context in chain. | 1329 // Load next context in chain. |
1330 __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); | 1330 __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); |
1331 __ jmp(&next); | 1331 __ jmp(&next); |
1332 __ bind(&fast); | 1332 __ bind(&fast); |
1333 } | 1333 } |
1334 | 1334 |
1335 // All extension objects were empty and it is safe to use a global | 1335 // All extension objects were empty and it is safe to use a global |
1336 // load IC call. | 1336 // load IC call. |
1337 __ mov(edx, GlobalObjectOperand()); | 1337 __ mov(LoadIC::ReceiverRegister(), GlobalObjectOperand()); |
1338 __ mov(ecx, var->name()); | 1338 __ mov(LoadIC::NameRegister(), var->name()); |
1339 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) | 1339 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) |
1340 ? NOT_CONTEXTUAL | 1340 ? NOT_CONTEXTUAL |
1341 : CONTEXTUAL; | 1341 : CONTEXTUAL; |
1342 | 1342 |
1343 CallLoadIC(mode); | 1343 CallLoadIC(mode); |
1344 } | 1344 } |
1345 | 1345 |
1346 | 1346 |
1347 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1347 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
1348 Label* slow) { | 1348 Label* slow) { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1408 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { | 1408 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
1409 // Record position before possible IC call. | 1409 // Record position before possible IC call. |
1410 SetSourcePosition(proxy->position()); | 1410 SetSourcePosition(proxy->position()); |
1411 Variable* var = proxy->var(); | 1411 Variable* var = proxy->var(); |
1412 | 1412 |
1413 // Three cases: global variables, lookup variables, and all other types of | 1413 // Three cases: global variables, lookup variables, and all other types of |
1414 // variables. | 1414 // variables. |
1415 switch (var->location()) { | 1415 switch (var->location()) { |
1416 case Variable::UNALLOCATED: { | 1416 case Variable::UNALLOCATED: { |
1417 Comment cmnt(masm_, "[ Global variable"); | 1417 Comment cmnt(masm_, "[ Global variable"); |
1418 // Use inline caching. Variable name is passed in ecx and the global | 1418 __ mov(LoadIC::ReceiverRegister(), GlobalObjectOperand()); |
1419 // object in eax. | 1419 __ mov(LoadIC::NameRegister(), var->name()); |
1420 __ mov(edx, GlobalObjectOperand()); | |
1421 __ mov(ecx, var->name()); | |
1422 CallLoadIC(CONTEXTUAL); | 1420 CallLoadIC(CONTEXTUAL); |
1423 context()->Plug(eax); | 1421 context()->Plug(eax); |
1424 break; | 1422 break; |
1425 } | 1423 } |
1426 | 1424 |
1427 case Variable::PARAMETER: | 1425 case Variable::PARAMETER: |
1428 case Variable::LOCAL: | 1426 case Variable::LOCAL: |
1429 case Variable::CONTEXT: { | 1427 case Variable::CONTEXT: { |
1430 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" | 1428 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" |
1431 : "[ Stack variable"); | 1429 : "[ Stack variable"); |
(...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1998 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); | 1996 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); |
1999 __ mov(context_register(), | 1997 __ mov(context_register(), |
2000 Operand(ebp, StandardFrameConstants::kContextOffset)); | 1998 Operand(ebp, StandardFrameConstants::kContextOffset)); |
2001 __ pop(eax); // result | 1999 __ pop(eax); // result |
2002 EmitReturnSequence(); | 2000 EmitReturnSequence(); |
2003 __ bind(&l_resume); // received in eax | 2001 __ bind(&l_resume); // received in eax |
2004 __ PopTryHandler(); | 2002 __ PopTryHandler(); |
2005 | 2003 |
2006 // receiver = iter; f = iter.next; arg = received; | 2004 // receiver = iter; f = iter.next; arg = received; |
2007 __ bind(&l_next); | 2005 __ bind(&l_next); |
2008 __ mov(ecx, isolate()->factory()->next_string()); // "next" | 2006 Register keyedload_receiver = KeyedLoadIC::ReceiverRegister(); |
2009 __ push(ecx); | 2007 Register keyedload_name = KeyedLoadIC::NameRegister(); |
| 2008 ASSERT(keyedload_receiver.is(edx)); |
| 2009 ASSERT(keyedload_name.is(ecx)); |
| 2010 |
| 2011 __ mov(keyedload_name, |
| 2012 isolate()->factory()->next_string()); // "next" |
| 2013 __ push(keyedload_name); |
2010 __ push(Operand(esp, 2 * kPointerSize)); // iter | 2014 __ push(Operand(esp, 2 * kPointerSize)); // iter |
2011 __ push(eax); // received | 2015 __ push(eax); // received |
2012 | 2016 |
2013 // result = receiver[f](arg); | 2017 // result = receiver[f](arg); |
2014 __ bind(&l_call); | 2018 __ bind(&l_call); |
2015 __ mov(edx, Operand(esp, kPointerSize)); | 2019 __ mov(keyedload_receiver, Operand(esp, kPointerSize)); |
2016 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2020 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
2017 CallIC(ic, TypeFeedbackId::None()); | 2021 CallIC(ic, TypeFeedbackId::None()); |
2018 __ mov(edi, eax); | 2022 __ mov(edi, eax); |
2019 __ mov(Operand(esp, 2 * kPointerSize), edi); | 2023 __ mov(Operand(esp, 2 * kPointerSize), edi); |
2020 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); | 2024 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); |
2021 __ CallStub(&stub); | 2025 __ CallStub(&stub); |
2022 | 2026 |
2023 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2027 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
2024 __ Drop(1); // The function is still on the stack; drop it. | 2028 __ Drop(1); // The function is still on the stack; drop it. |
2025 | 2029 |
2026 // if (!result.done) goto l_try; | 2030 // if (!result.done) goto l_try; |
2027 __ bind(&l_loop); | 2031 __ bind(&l_loop); |
2028 __ push(eax); // save result | 2032 __ push(eax); // save result |
2029 __ mov(edx, eax); // result | 2033 Register load_receiver = LoadIC::ReceiverRegister(); |
2030 __ mov(ecx, isolate()->factory()->done_string()); // "done" | 2034 Register load_name = LoadIC::NameRegister(); |
| 2035 ASSERT(load_receiver.is(edx)); |
| 2036 ASSERT(load_name.is(ecx)); |
| 2037 __ mov(load_receiver, eax); // result |
| 2038 __ mov(load_name, |
| 2039 isolate()->factory()->done_string()); // "done" |
2031 CallLoadIC(NOT_CONTEXTUAL); // result.done in eax | 2040 CallLoadIC(NOT_CONTEXTUAL); // result.done in eax |
2032 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); | 2041 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); |
2033 CallIC(bool_ic); | 2042 CallIC(bool_ic); |
2034 __ test(eax, eax); | 2043 __ test(eax, eax); |
2035 __ j(zero, &l_try); | 2044 __ j(zero, &l_try); |
2036 | 2045 |
2037 // result.value | 2046 // result.value |
2038 __ pop(edx); // result | 2047 __ pop(load_receiver); // result |
2039 __ mov(ecx, isolate()->factory()->value_string()); // "value" | 2048 __ mov(load_name, |
| 2049 isolate()->factory()->value_string()); // "value" |
2040 CallLoadIC(NOT_CONTEXTUAL); // result.value in eax | 2050 CallLoadIC(NOT_CONTEXTUAL); // result.value in eax |
2041 context()->DropAndPlug(2, eax); // drop iter and g | 2051 context()->DropAndPlug(2, eax); // drop iter and g |
2042 break; | 2052 break; |
2043 } | 2053 } |
2044 } | 2054 } |
2045 } | 2055 } |
2046 | 2056 |
2047 | 2057 |
2048 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 2058 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
2049 Expression *value, | 2059 Expression *value, |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2189 // root set. | 2199 // root set. |
2190 __ RecordWriteField(eax, JSGeneratorObject::kResultValuePropertyOffset, | 2200 __ RecordWriteField(eax, JSGeneratorObject::kResultValuePropertyOffset, |
2191 ecx, edx); | 2201 ecx, edx); |
2192 } | 2202 } |
2193 | 2203 |
2194 | 2204 |
2195 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2205 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
2196 SetSourcePosition(prop->position()); | 2206 SetSourcePosition(prop->position()); |
2197 Literal* key = prop->key()->AsLiteral(); | 2207 Literal* key = prop->key()->AsLiteral(); |
2198 ASSERT(!key->value()->IsSmi()); | 2208 ASSERT(!key->value()->IsSmi()); |
2199 __ mov(ecx, Immediate(key->value())); | 2209 __ mov(LoadIC::NameRegister(), Immediate(key->value())); |
2200 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); | 2210 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
2201 } | 2211 } |
2202 | 2212 |
2203 | 2213 |
2204 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2214 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
2205 SetSourcePosition(prop->position()); | 2215 SetSourcePosition(prop->position()); |
2206 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2216 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
2207 CallIC(ic, prop->PropertyFeedbackId()); | 2217 CallIC(ic, prop->PropertyFeedbackId()); |
2208 } | 2218 } |
2209 | 2219 |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2487 context()->Plug(eax); | 2497 context()->Plug(eax); |
2488 } | 2498 } |
2489 | 2499 |
2490 | 2500 |
2491 void FullCodeGenerator::VisitProperty(Property* expr) { | 2501 void FullCodeGenerator::VisitProperty(Property* expr) { |
2492 Comment cmnt(masm_, "[ Property"); | 2502 Comment cmnt(masm_, "[ Property"); |
2493 Expression* key = expr->key(); | 2503 Expression* key = expr->key(); |
2494 | 2504 |
2495 if (key->IsPropertyName()) { | 2505 if (key->IsPropertyName()) { |
2496 VisitForAccumulatorValue(expr->obj()); | 2506 VisitForAccumulatorValue(expr->obj()); |
2497 __ mov(edx, result_register()); | 2507 __ mov(LoadIC::ReceiverRegister(), result_register()); |
2498 EmitNamedPropertyLoad(expr); | 2508 EmitNamedPropertyLoad(expr); |
2499 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2509 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
2500 context()->Plug(eax); | 2510 context()->Plug(eax); |
2501 } else { | 2511 } else { |
2502 VisitForStackValue(expr->obj()); | 2512 VisitForStackValue(expr->obj()); |
2503 VisitForAccumulatorValue(expr->key()); | 2513 VisitForAccumulatorValue(expr->key()); |
2504 __ pop(edx); // Object. | 2514 __ pop(KeyedLoadIC::ReceiverRegister()); // Object. |
2505 __ mov(ecx, result_register()); // Key. | 2515 __ mov(KeyedLoadIC::NameRegister(), result_register()); // Key. |
2506 EmitKeyedPropertyLoad(expr); | 2516 EmitKeyedPropertyLoad(expr); |
2507 context()->Plug(eax); | 2517 context()->Plug(eax); |
2508 } | 2518 } |
2509 } | 2519 } |
2510 | 2520 |
2511 | 2521 |
2512 void FullCodeGenerator::CallIC(Handle<Code> code, | 2522 void FullCodeGenerator::CallIC(Handle<Code> code, |
2513 TypeFeedbackId ast_id) { | 2523 TypeFeedbackId ast_id) { |
2514 ic_total_count_++; | 2524 ic_total_count_++; |
2515 __ call(code, RelocInfo::CODE_TARGET, ast_id); | 2525 __ call(code, RelocInfo::CODE_TARGET, ast_id); |
(...skipping 12 matching lines...) Expand all Loading... |
2528 { StackValueContext context(this); | 2538 { StackValueContext context(this); |
2529 EmitVariableLoad(callee->AsVariableProxy()); | 2539 EmitVariableLoad(callee->AsVariableProxy()); |
2530 PrepareForBailout(callee, NO_REGISTERS); | 2540 PrepareForBailout(callee, NO_REGISTERS); |
2531 } | 2541 } |
2532 // Push undefined as receiver. This is patched in the method prologue if it | 2542 // Push undefined as receiver. This is patched in the method prologue if it |
2533 // is a sloppy mode method. | 2543 // is a sloppy mode method. |
2534 __ push(Immediate(isolate()->factory()->undefined_value())); | 2544 __ push(Immediate(isolate()->factory()->undefined_value())); |
2535 } else { | 2545 } else { |
2536 // Load the function from the receiver. | 2546 // Load the function from the receiver. |
2537 ASSERT(callee->IsProperty()); | 2547 ASSERT(callee->IsProperty()); |
2538 __ mov(edx, Operand(esp, 0)); | 2548 __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0)); |
2539 EmitNamedPropertyLoad(callee->AsProperty()); | 2549 EmitNamedPropertyLoad(callee->AsProperty()); |
2540 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2550 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2541 // Push the target function under the receiver. | 2551 // Push the target function under the receiver. |
2542 __ push(Operand(esp, 0)); | 2552 __ push(Operand(esp, 0)); |
2543 __ mov(Operand(esp, kPointerSize), eax); | 2553 __ mov(Operand(esp, kPointerSize), eax); |
2544 } | 2554 } |
2545 | 2555 |
2546 EmitCall(expr, call_type); | 2556 EmitCall(expr, call_type); |
2547 } | 2557 } |
2548 | 2558 |
2549 | 2559 |
2550 // Code common for calls using the IC. | 2560 // Code common for calls using the IC. |
2551 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 2561 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
2552 Expression* key) { | 2562 Expression* key) { |
2553 // Load the key. | 2563 // Load the key. |
2554 VisitForAccumulatorValue(key); | 2564 VisitForAccumulatorValue(key); |
2555 | 2565 |
2556 Expression* callee = expr->expression(); | 2566 Expression* callee = expr->expression(); |
2557 | 2567 |
2558 // Load the function from the receiver. | 2568 // Load the function from the receiver. |
2559 ASSERT(callee->IsProperty()); | 2569 ASSERT(callee->IsProperty()); |
2560 __ mov(edx, Operand(esp, 0)); | 2570 __ mov(KeyedLoadIC::ReceiverRegister(), Operand(esp, 0)); |
2561 // Move the key into the right register for the keyed load IC. | 2571 // Move the key into the right register for the keyed load IC. |
2562 __ mov(ecx, eax); | 2572 __ mov(KeyedLoadIC::NameRegister(), eax); |
2563 EmitKeyedPropertyLoad(callee->AsProperty()); | 2573 EmitKeyedPropertyLoad(callee->AsProperty()); |
2564 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2574 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2565 | 2575 |
2566 // Push the target function under the receiver. | 2576 // Push the target function under the receiver. |
2567 __ push(Operand(esp, 0)); | 2577 __ push(Operand(esp, 0)); |
2568 __ mov(Operand(esp, kPointerSize), eax); | 2578 __ mov(Operand(esp, kPointerSize), eax); |
2569 | 2579 |
2570 EmitCall(expr, CallIC::METHOD); | 2580 EmitCall(expr, CallIC::METHOD); |
2571 } | 2581 } |
2572 | 2582 |
(...skipping 1436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4009 | 4019 |
4010 Comment cmnt(masm_, "[ CallRuntime"); | 4020 Comment cmnt(masm_, "[ CallRuntime"); |
4011 ZoneList<Expression*>* args = expr->arguments(); | 4021 ZoneList<Expression*>* args = expr->arguments(); |
4012 | 4022 |
4013 if (expr->is_jsruntime()) { | 4023 if (expr->is_jsruntime()) { |
4014 // Push the builtins object as receiver. | 4024 // Push the builtins object as receiver. |
4015 __ mov(eax, GlobalObjectOperand()); | 4025 __ mov(eax, GlobalObjectOperand()); |
4016 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); | 4026 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); |
4017 | 4027 |
4018 // Load the function from the receiver. | 4028 // Load the function from the receiver. |
4019 __ mov(edx, Operand(esp, 0)); | 4029 __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0)); |
4020 __ mov(ecx, Immediate(expr->name())); | 4030 __ mov(LoadIC::NameRegister(), Immediate(expr->name())); |
4021 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); | 4031 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); |
4022 | 4032 |
4023 // Push the target function under the receiver. | 4033 // Push the target function under the receiver. |
4024 __ push(Operand(esp, 0)); | 4034 __ push(Operand(esp, 0)); |
4025 __ mov(Operand(esp, kPointerSize), eax); | 4035 __ mov(Operand(esp, kPointerSize), eax); |
4026 | 4036 |
4027 // Code common for calls using the IC. | 4037 // Code common for calls using the IC. |
4028 ZoneList<Expression*>* args = expr->arguments(); | 4038 ZoneList<Expression*>* args = expr->arguments(); |
4029 int arg_count = args->length(); | 4039 int arg_count = args->length(); |
4030 for (int i = 0; i < arg_count; i++) { | 4040 for (int i = 0; i < arg_count; i++) { |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4193 AccumulatorValueContext context(this); | 4203 AccumulatorValueContext context(this); |
4194 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4204 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
4195 } else { | 4205 } else { |
4196 // Reserve space for result of postfix operation. | 4206 // Reserve space for result of postfix operation. |
4197 if (expr->is_postfix() && !context()->IsEffect()) { | 4207 if (expr->is_postfix() && !context()->IsEffect()) { |
4198 __ push(Immediate(Smi::FromInt(0))); | 4208 __ push(Immediate(Smi::FromInt(0))); |
4199 } | 4209 } |
4200 if (assign_type == NAMED_PROPERTY) { | 4210 if (assign_type == NAMED_PROPERTY) { |
4201 // Put the object both on the stack and in edx. | 4211 // Put the object both on the stack and in edx. |
4202 VisitForAccumulatorValue(prop->obj()); | 4212 VisitForAccumulatorValue(prop->obj()); |
| 4213 ASSERT(!eax.is(LoadIC::ReceiverRegister())); |
4203 __ push(eax); | 4214 __ push(eax); |
4204 __ mov(edx, eax); | 4215 __ mov(LoadIC::ReceiverRegister(), eax); |
4205 EmitNamedPropertyLoad(prop); | 4216 EmitNamedPropertyLoad(prop); |
4206 } else { | 4217 } else { |
4207 VisitForStackValue(prop->obj()); | 4218 VisitForStackValue(prop->obj()); |
4208 VisitForStackValue(prop->key()); | 4219 VisitForStackValue(prop->key()); |
4209 __ mov(edx, Operand(esp, kPointerSize)); // Object. | 4220 __ mov(KeyedLoadIC::ReceiverRegister(), |
4210 __ mov(ecx, Operand(esp, 0)); // Key. | 4221 Operand(esp, kPointerSize)); // Object. |
| 4222 __ mov(KeyedLoadIC::NameRegister(), Operand(esp, 0)); // Key. |
4211 EmitKeyedPropertyLoad(prop); | 4223 EmitKeyedPropertyLoad(prop); |
4212 } | 4224 } |
4213 } | 4225 } |
4214 | 4226 |
4215 // We need a second deoptimization point after loading the value | 4227 // We need a second deoptimization point after loading the value |
4216 // in case evaluating the property load my have a side effect. | 4228 // in case evaluating the property load my have a side effect. |
4217 if (assign_type == VARIABLE) { | 4229 if (assign_type == VARIABLE) { |
4218 PrepareForBailout(expr->expression(), TOS_REG); | 4230 PrepareForBailout(expr->expression(), TOS_REG); |
4219 } else { | 4231 } else { |
4220 PrepareForBailoutForId(prop->LoadId(), TOS_REG); | 4232 PrepareForBailoutForId(prop->LoadId(), TOS_REG); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4357 } | 4369 } |
4358 | 4370 |
4359 | 4371 |
4360 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 4372 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
4361 VariableProxy* proxy = expr->AsVariableProxy(); | 4373 VariableProxy* proxy = expr->AsVariableProxy(); |
4362 ASSERT(!context()->IsEffect()); | 4374 ASSERT(!context()->IsEffect()); |
4363 ASSERT(!context()->IsTest()); | 4375 ASSERT(!context()->IsTest()); |
4364 | 4376 |
4365 if (proxy != NULL && proxy->var()->IsUnallocated()) { | 4377 if (proxy != NULL && proxy->var()->IsUnallocated()) { |
4366 Comment cmnt(masm_, "[ Global variable"); | 4378 Comment cmnt(masm_, "[ Global variable"); |
4367 __ mov(edx, GlobalObjectOperand()); | 4379 __ mov(LoadIC::ReceiverRegister(), GlobalObjectOperand()); |
4368 __ mov(ecx, Immediate(proxy->name())); | 4380 __ mov(LoadIC::NameRegister(), Immediate(proxy->name())); |
4369 // Use a regular load, not a contextual load, to avoid a reference | 4381 // Use a regular load, not a contextual load, to avoid a reference |
4370 // error. | 4382 // error. |
4371 CallLoadIC(NOT_CONTEXTUAL); | 4383 CallLoadIC(NOT_CONTEXTUAL); |
4372 PrepareForBailout(expr, TOS_REG); | 4384 PrepareForBailout(expr, TOS_REG); |
4373 context()->Plug(eax); | 4385 context()->Plug(eax); |
4374 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 4386 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
4375 Comment cmnt(masm_, "[ Lookup slot"); | 4387 Comment cmnt(masm_, "[ Lookup slot"); |
4376 Label done, slow; | 4388 Label done, slow; |
4377 | 4389 |
4378 // Generate code for loading from variables potentially shadowed | 4390 // Generate code for loading from variables potentially shadowed |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4792 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4804 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
4793 Assembler::target_address_at(call_target_address, | 4805 Assembler::target_address_at(call_target_address, |
4794 unoptimized_code)); | 4806 unoptimized_code)); |
4795 return OSR_AFTER_STACK_CHECK; | 4807 return OSR_AFTER_STACK_CHECK; |
4796 } | 4808 } |
4797 | 4809 |
4798 | 4810 |
4799 } } // namespace v8::internal | 4811 } } // namespace v8::internal |
4800 | 4812 |
4801 #endif // V8_TARGET_ARCH_X87 | 4813 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |