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_X64 | 7 #if V8_TARGET_ARCH_X64 |
8 | 8 |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 1354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1365 __ cmpp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0)); | 1365 __ cmpp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0)); |
1366 __ j(not_equal, slow); | 1366 __ j(not_equal, slow); |
1367 // Load next context in chain. | 1367 // Load next context in chain. |
1368 __ movp(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); | 1368 __ movp(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); |
1369 __ jmp(&next); | 1369 __ jmp(&next); |
1370 __ bind(&fast); | 1370 __ bind(&fast); |
1371 } | 1371 } |
1372 | 1372 |
1373 // All extension objects were empty and it is safe to use a global | 1373 // All extension objects were empty and it is safe to use a global |
1374 // load IC call. | 1374 // load IC call. |
1375 __ movp(rax, GlobalObjectOperand()); | 1375 __ movp(LoadIC::ReceiverRegister(), GlobalObjectOperand()); |
1376 __ Move(rcx, var->name()); | 1376 __ Move(LoadIC::NameRegister(), var->name()); |
1377 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) | 1377 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) |
1378 ? NOT_CONTEXTUAL | 1378 ? NOT_CONTEXTUAL |
1379 : CONTEXTUAL; | 1379 : CONTEXTUAL; |
1380 CallLoadIC(mode); | 1380 CallLoadIC(mode); |
1381 } | 1381 } |
1382 | 1382 |
1383 | 1383 |
1384 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1384 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
1385 Label* slow) { | 1385 Label* slow) { |
1386 ASSERT(var->IsContextSlot()); | 1386 ASSERT(var->IsContextSlot()); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1445 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { | 1445 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
1446 // Record position before possible IC call. | 1446 // Record position before possible IC call. |
1447 SetSourcePosition(proxy->position()); | 1447 SetSourcePosition(proxy->position()); |
1448 Variable* var = proxy->var(); | 1448 Variable* var = proxy->var(); |
1449 | 1449 |
1450 // Three cases: global variables, lookup variables, and all other types of | 1450 // Three cases: global variables, lookup variables, and all other types of |
1451 // variables. | 1451 // variables. |
1452 switch (var->location()) { | 1452 switch (var->location()) { |
1453 case Variable::UNALLOCATED: { | 1453 case Variable::UNALLOCATED: { |
1454 Comment cmnt(masm_, "[ Global variable"); | 1454 Comment cmnt(masm_, "[ Global variable"); |
1455 // Use inline caching. Variable name is passed in rcx and the global | 1455 __ Move(LoadIC::NameRegister(), var->name()); |
1456 // object on the stack. | 1456 __ movp(LoadIC::ReceiverRegister(), GlobalObjectOperand()); |
1457 __ Move(rcx, var->name()); | |
1458 __ movp(rax, GlobalObjectOperand()); | |
1459 CallLoadIC(CONTEXTUAL); | 1457 CallLoadIC(CONTEXTUAL); |
1460 context()->Plug(rax); | 1458 context()->Plug(rax); |
1461 break; | 1459 break; |
1462 } | 1460 } |
1463 | 1461 |
1464 case Variable::PARAMETER: | 1462 case Variable::PARAMETER: |
1465 case Variable::LOCAL: | 1463 case Variable::LOCAL: |
1466 case Variable::CONTEXT: { | 1464 case Variable::CONTEXT: { |
1467 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context slot" | 1465 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context slot" |
1468 : "[ Stack slot"); | 1466 : "[ Stack slot"); |
(...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2037 __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1); | 2035 __ CallRuntime(Runtime::kHiddenSuspendJSGeneratorObject, 1); |
2038 __ movp(context_register(), | 2036 __ movp(context_register(), |
2039 Operand(rbp, StandardFrameConstants::kContextOffset)); | 2037 Operand(rbp, StandardFrameConstants::kContextOffset)); |
2040 __ Pop(rax); // result | 2038 __ Pop(rax); // result |
2041 EmitReturnSequence(); | 2039 EmitReturnSequence(); |
2042 __ bind(&l_resume); // received in rax | 2040 __ bind(&l_resume); // received in rax |
2043 __ PopTryHandler(); | 2041 __ PopTryHandler(); |
2044 | 2042 |
2045 // receiver = iter; f = 'next'; arg = received; | 2043 // receiver = iter; f = 'next'; arg = received; |
2046 __ bind(&l_next); | 2044 __ bind(&l_next); |
| 2045 Register keyedload_receiver = KeyedLoadIC::ReceiverRegister(); |
| 2046 Register keyedload_name = KeyedLoadIC::NameRegister(); |
| 2047 ASSERT(keyedload_receiver.is(rdx)); |
| 2048 ASSERT(keyedload_name.is(rax)); |
| 2049 |
2047 __ LoadRoot(rcx, Heap::knext_stringRootIndex); // "next" | 2050 __ LoadRoot(rcx, Heap::knext_stringRootIndex); // "next" |
2048 __ Push(rcx); | 2051 __ Push(rcx); |
2049 __ Push(Operand(rsp, 2 * kPointerSize)); // iter | 2052 __ Push(Operand(rsp, 2 * kPointerSize)); // iter |
2050 __ Push(rax); // received | 2053 __ Push(rax); // received |
2051 | 2054 |
2052 // result = receiver[f](arg); | 2055 // result = receiver[f](arg); |
2053 __ bind(&l_call); | 2056 __ bind(&l_call); |
2054 __ movp(rdx, Operand(rsp, kPointerSize)); | 2057 __ movp(keyedload_receiver, Operand(rsp, kPointerSize)); |
2055 __ movp(rax, Operand(rsp, 2 * kPointerSize)); | 2058 __ movp(keyedload_name, Operand(rsp, 2 * kPointerSize)); |
2056 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2059 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
2057 CallIC(ic, TypeFeedbackId::None()); | 2060 CallIC(ic, TypeFeedbackId::None()); |
2058 __ movp(rdi, rax); | 2061 __ movp(rdi, rax); |
2059 __ movp(Operand(rsp, 2 * kPointerSize), rdi); | 2062 __ movp(Operand(rsp, 2 * kPointerSize), rdi); |
2060 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); | 2063 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); |
2061 __ CallStub(&stub); | 2064 __ CallStub(&stub); |
2062 | 2065 |
2063 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2066 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2064 __ Drop(1); // The function is still on the stack; drop it. | 2067 __ Drop(1); // The function is still on the stack; drop it. |
2065 | 2068 |
2066 // if (!result.done) goto l_try; | 2069 // if (!result.done) goto l_try; |
2067 __ bind(&l_loop); | 2070 __ bind(&l_loop); |
2068 __ Push(rax); // save result | 2071 Register load_receiver = LoadIC::ReceiverRegister(); |
2069 __ LoadRoot(rcx, Heap::kdone_stringRootIndex); // "done" | 2072 Register load_name = LoadIC::NameRegister(); |
2070 CallLoadIC(NOT_CONTEXTUAL); // result.done in rax | 2073 ASSERT(load_receiver.is(rax)); |
| 2074 ASSERT(load_name.is(rcx)); |
| 2075 |
| 2076 __ Push(load_receiver); // save result |
| 2077 __ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done" |
| 2078 CallLoadIC(NOT_CONTEXTUAL); // rax=result.done |
2071 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); | 2079 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); |
2072 CallIC(bool_ic); | 2080 CallIC(bool_ic); |
2073 __ testp(result_register(), result_register()); | 2081 __ testp(result_register(), result_register()); |
2074 __ j(zero, &l_try); | 2082 __ j(zero, &l_try); |
2075 | 2083 |
2076 // result.value | 2084 // result.value |
2077 __ Pop(rax); // result | 2085 __ Pop(load_receiver); // result |
2078 __ LoadRoot(rcx, Heap::kvalue_stringRootIndex); // "value" | 2086 __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value" |
2079 CallLoadIC(NOT_CONTEXTUAL); // result.value in rax | 2087 CallLoadIC(NOT_CONTEXTUAL); // result.value in rax |
2080 context()->DropAndPlug(2, rax); // drop iter and g | 2088 context()->DropAndPlug(2, rax); // drop iter and g |
2081 break; | 2089 break; |
2082 } | 2090 } |
2083 } | 2091 } |
2084 } | 2092 } |
2085 | 2093 |
2086 | 2094 |
2087 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 2095 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
2088 Expression *value, | 2096 Expression *value, |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2229 // Only the value field needs a write barrier, as the other values are in the | 2237 // Only the value field needs a write barrier, as the other values are in the |
2230 // root set. | 2238 // root set. |
2231 __ RecordWriteField(rax, JSGeneratorObject::kResultValuePropertyOffset, | 2239 __ RecordWriteField(rax, JSGeneratorObject::kResultValuePropertyOffset, |
2232 rcx, rdx, kDontSaveFPRegs); | 2240 rcx, rdx, kDontSaveFPRegs); |
2233 } | 2241 } |
2234 | 2242 |
2235 | 2243 |
2236 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2244 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
2237 SetSourcePosition(prop->position()); | 2245 SetSourcePosition(prop->position()); |
2238 Literal* key = prop->key()->AsLiteral(); | 2246 Literal* key = prop->key()->AsLiteral(); |
2239 __ Move(rcx, key->value()); | 2247 __ Move(LoadIC::NameRegister(), key->value()); |
2240 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); | 2248 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
2241 } | 2249 } |
2242 | 2250 |
2243 | 2251 |
2244 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2252 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
2245 SetSourcePosition(prop->position()); | 2253 SetSourcePosition(prop->position()); |
2246 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2254 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
2247 CallIC(ic, prop->PropertyFeedbackId()); | 2255 CallIC(ic, prop->PropertyFeedbackId()); |
2248 } | 2256 } |
2249 | 2257 |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2488 context()->Plug(rax); | 2496 context()->Plug(rax); |
2489 } | 2497 } |
2490 | 2498 |
2491 | 2499 |
2492 void FullCodeGenerator::VisitProperty(Property* expr) { | 2500 void FullCodeGenerator::VisitProperty(Property* expr) { |
2493 Comment cmnt(masm_, "[ Property"); | 2501 Comment cmnt(masm_, "[ Property"); |
2494 Expression* key = expr->key(); | 2502 Expression* key = expr->key(); |
2495 | 2503 |
2496 if (key->IsPropertyName()) { | 2504 if (key->IsPropertyName()) { |
2497 VisitForAccumulatorValue(expr->obj()); | 2505 VisitForAccumulatorValue(expr->obj()); |
| 2506 ASSERT(rax.is(LoadIC::ReceiverRegister())); |
2498 EmitNamedPropertyLoad(expr); | 2507 EmitNamedPropertyLoad(expr); |
2499 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2508 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
2500 context()->Plug(rax); | 2509 context()->Plug(rax); |
2501 } else { | 2510 } else { |
2502 VisitForStackValue(expr->obj()); | 2511 VisitForStackValue(expr->obj()); |
2503 VisitForAccumulatorValue(expr->key()); | 2512 VisitForAccumulatorValue(expr->key()); |
2504 __ Pop(rdx); | 2513 ASSERT(rax.is(KeyedLoadIC::NameRegister())); |
| 2514 __ Pop(KeyedLoadIC::ReceiverRegister()); |
2505 EmitKeyedPropertyLoad(expr); | 2515 EmitKeyedPropertyLoad(expr); |
2506 context()->Plug(rax); | 2516 context()->Plug(rax); |
2507 } | 2517 } |
2508 } | 2518 } |
2509 | 2519 |
2510 | 2520 |
2511 void FullCodeGenerator::CallIC(Handle<Code> code, | 2521 void FullCodeGenerator::CallIC(Handle<Code> code, |
2512 TypeFeedbackId ast_id) { | 2522 TypeFeedbackId ast_id) { |
2513 ic_total_count_++; | 2523 ic_total_count_++; |
2514 __ call(code, RelocInfo::CODE_TARGET, ast_id); | 2524 __ call(code, RelocInfo::CODE_TARGET, ast_id); |
(...skipping 12 matching lines...) Expand all Loading... |
2527 { StackValueContext context(this); | 2537 { StackValueContext context(this); |
2528 EmitVariableLoad(callee->AsVariableProxy()); | 2538 EmitVariableLoad(callee->AsVariableProxy()); |
2529 PrepareForBailout(callee, NO_REGISTERS); | 2539 PrepareForBailout(callee, NO_REGISTERS); |
2530 } | 2540 } |
2531 // Push undefined as receiver. This is patched in the method prologue if it | 2541 // Push undefined as receiver. This is patched in the method prologue if it |
2532 // is a sloppy mode method. | 2542 // is a sloppy mode method. |
2533 __ Push(isolate()->factory()->undefined_value()); | 2543 __ Push(isolate()->factory()->undefined_value()); |
2534 } else { | 2544 } else { |
2535 // Load the function from the receiver. | 2545 // Load the function from the receiver. |
2536 ASSERT(callee->IsProperty()); | 2546 ASSERT(callee->IsProperty()); |
2537 __ movp(rax, Operand(rsp, 0)); | 2547 __ movp(LoadIC::ReceiverRegister(), Operand(rsp, 0)); |
2538 EmitNamedPropertyLoad(callee->AsProperty()); | 2548 EmitNamedPropertyLoad(callee->AsProperty()); |
2539 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2549 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2540 // Push the target function under the receiver. | 2550 // Push the target function under the receiver. |
2541 __ Push(Operand(rsp, 0)); | 2551 __ Push(Operand(rsp, 0)); |
2542 __ movp(Operand(rsp, kPointerSize), rax); | 2552 __ movp(Operand(rsp, kPointerSize), rax); |
2543 } | 2553 } |
2544 | 2554 |
2545 EmitCall(expr, call_type); | 2555 EmitCall(expr, call_type); |
2546 } | 2556 } |
2547 | 2557 |
2548 | 2558 |
2549 // Common code for calls using the IC. | 2559 // Common code for calls using the IC. |
2550 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 2560 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
2551 Expression* key) { | 2561 Expression* key) { |
2552 // Load the key. | 2562 // Load the key. |
2553 VisitForAccumulatorValue(key); | 2563 VisitForAccumulatorValue(key); |
| 2564 ASSERT(rax.is(KeyedLoadIC::NameRegister())); |
2554 | 2565 |
2555 Expression* callee = expr->expression(); | 2566 Expression* callee = expr->expression(); |
2556 | 2567 |
2557 // Load the function from the receiver. | 2568 // Load the function from the receiver. |
2558 ASSERT(callee->IsProperty()); | 2569 ASSERT(callee->IsProperty()); |
2559 __ movp(rdx, Operand(rsp, 0)); | 2570 __ movp(KeyedLoadIC::ReceiverRegister(), Operand(rsp, 0)); |
2560 EmitKeyedPropertyLoad(callee->AsProperty()); | 2571 EmitKeyedPropertyLoad(callee->AsProperty()); |
2561 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2572 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2562 | 2573 |
2563 // Push the target function under the receiver. | 2574 // Push the target function under the receiver. |
2564 __ Push(Operand(rsp, 0)); | 2575 __ Push(Operand(rsp, 0)); |
2565 __ movp(Operand(rsp, kPointerSize), rax); | 2576 __ movp(Operand(rsp, kPointerSize), rax); |
2566 | 2577 |
2567 EmitCall(expr, CallIC::METHOD); | 2578 EmitCall(expr, CallIC::METHOD); |
2568 } | 2579 } |
2569 | 2580 |
(...skipping 1457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4027 Comment cmnt(masm_, "[ CallRuntime"); | 4038 Comment cmnt(masm_, "[ CallRuntime"); |
4028 ZoneList<Expression*>* args = expr->arguments(); | 4039 ZoneList<Expression*>* args = expr->arguments(); |
4029 int arg_count = args->length(); | 4040 int arg_count = args->length(); |
4030 | 4041 |
4031 if (expr->is_jsruntime()) { | 4042 if (expr->is_jsruntime()) { |
4032 // Push the builtins object as receiver. | 4043 // Push the builtins object as receiver. |
4033 __ movp(rax, GlobalObjectOperand()); | 4044 __ movp(rax, GlobalObjectOperand()); |
4034 __ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); | 4045 __ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); |
4035 | 4046 |
4036 // Load the function from the receiver. | 4047 // Load the function from the receiver. |
4037 __ movp(rax, Operand(rsp, 0)); | 4048 __ movp(LoadIC::ReceiverRegister(), Operand(rsp, 0)); |
4038 __ Move(rcx, expr->name()); | 4049 __ Move(LoadIC::NameRegister(), expr->name()); |
4039 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); | 4050 CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); |
4040 | 4051 |
4041 // Push the target function under the receiver. | 4052 // Push the target function under the receiver. |
4042 __ Push(Operand(rsp, 0)); | 4053 __ Push(Operand(rsp, 0)); |
4043 __ movp(Operand(rsp, kPointerSize), rax); | 4054 __ movp(Operand(rsp, kPointerSize), rax); |
4044 | 4055 |
4045 // Push the arguments ("left-to-right"). | 4056 // Push the arguments ("left-to-right"). |
4046 for (int i = 0; i < arg_count; i++) { | 4057 for (int i = 0; i < arg_count; i++) { |
4047 VisitForStackValue(args->at(i)); | 4058 VisitForStackValue(args->at(i)); |
4048 } | 4059 } |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4207 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); | 4218 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); |
4208 AccumulatorValueContext context(this); | 4219 AccumulatorValueContext context(this); |
4209 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4220 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
4210 } else { | 4221 } else { |
4211 // Reserve space for result of postfix operation. | 4222 // Reserve space for result of postfix operation. |
4212 if (expr->is_postfix() && !context()->IsEffect()) { | 4223 if (expr->is_postfix() && !context()->IsEffect()) { |
4213 __ Push(Smi::FromInt(0)); | 4224 __ Push(Smi::FromInt(0)); |
4214 } | 4225 } |
4215 if (assign_type == NAMED_PROPERTY) { | 4226 if (assign_type == NAMED_PROPERTY) { |
4216 VisitForAccumulatorValue(prop->obj()); | 4227 VisitForAccumulatorValue(prop->obj()); |
| 4228 ASSERT(rax.is(LoadIC::ReceiverRegister())); |
4217 __ Push(rax); // Copy of receiver, needed for later store. | 4229 __ Push(rax); // Copy of receiver, needed for later store. |
4218 EmitNamedPropertyLoad(prop); | 4230 EmitNamedPropertyLoad(prop); |
4219 } else { | 4231 } else { |
4220 VisitForStackValue(prop->obj()); | 4232 VisitForStackValue(prop->obj()); |
4221 VisitForAccumulatorValue(prop->key()); | 4233 VisitForAccumulatorValue(prop->key()); |
4222 __ movp(rdx, Operand(rsp, 0)); // Leave receiver on stack | 4234 ASSERT(rax.is(KeyedLoadIC::NameRegister())); |
4223 __ Push(rax); // Copy of key, needed for later store. | 4235 // Leave receiver on stack |
| 4236 __ movp(KeyedLoadIC::ReceiverRegister(), Operand(rsp, 0)); |
| 4237 // Copy of key, needed for later store. |
| 4238 __ Push(KeyedLoadIC::NameRegister()); |
4224 EmitKeyedPropertyLoad(prop); | 4239 EmitKeyedPropertyLoad(prop); |
4225 } | 4240 } |
4226 } | 4241 } |
4227 | 4242 |
4228 // We need a second deoptimization point after loading the value | 4243 // We need a second deoptimization point after loading the value |
4229 // in case evaluating the property load my have a side effect. | 4244 // in case evaluating the property load my have a side effect. |
4230 if (assign_type == VARIABLE) { | 4245 if (assign_type == VARIABLE) { |
4231 PrepareForBailout(expr->expression(), TOS_REG); | 4246 PrepareForBailout(expr->expression(), TOS_REG); |
4232 } else { | 4247 } else { |
4233 PrepareForBailoutForId(prop->LoadId(), TOS_REG); | 4248 PrepareForBailoutForId(prop->LoadId(), TOS_REG); |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4366 } | 4381 } |
4367 | 4382 |
4368 | 4383 |
4369 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 4384 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
4370 VariableProxy* proxy = expr->AsVariableProxy(); | 4385 VariableProxy* proxy = expr->AsVariableProxy(); |
4371 ASSERT(!context()->IsEffect()); | 4386 ASSERT(!context()->IsEffect()); |
4372 ASSERT(!context()->IsTest()); | 4387 ASSERT(!context()->IsTest()); |
4373 | 4388 |
4374 if (proxy != NULL && proxy->var()->IsUnallocated()) { | 4389 if (proxy != NULL && proxy->var()->IsUnallocated()) { |
4375 Comment cmnt(masm_, "[ Global variable"); | 4390 Comment cmnt(masm_, "[ Global variable"); |
4376 __ Move(rcx, proxy->name()); | 4391 __ Move(LoadIC::NameRegister(), proxy->name()); |
4377 __ movp(rax, GlobalObjectOperand()); | 4392 __ movp(LoadIC::ReceiverRegister(), GlobalObjectOperand()); |
4378 // Use a regular load, not a contextual load, to avoid a reference | 4393 // Use a regular load, not a contextual load, to avoid a reference |
4379 // error. | 4394 // error. |
4380 CallLoadIC(NOT_CONTEXTUAL); | 4395 CallLoadIC(NOT_CONTEXTUAL); |
4381 PrepareForBailout(expr, TOS_REG); | 4396 PrepareForBailout(expr, TOS_REG); |
4382 context()->Plug(rax); | 4397 context()->Plug(rax); |
4383 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 4398 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
4384 Comment cmnt(masm_, "[ Lookup slot"); | 4399 Comment cmnt(masm_, "[ Lookup slot"); |
4385 Label done, slow; | 4400 Label done, slow; |
4386 | 4401 |
4387 // Generate code for loading from variables potentially shadowed | 4402 // Generate code for loading from variables potentially shadowed |
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4804 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4819 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
4805 Assembler::target_address_at(call_target_address, | 4820 Assembler::target_address_at(call_target_address, |
4806 unoptimized_code)); | 4821 unoptimized_code)); |
4807 return OSR_AFTER_STACK_CHECK; | 4822 return OSR_AFTER_STACK_CHECK; |
4808 } | 4823 } |
4809 | 4824 |
4810 | 4825 |
4811 } } // namespace v8::internal | 4826 } } // namespace v8::internal |
4812 | 4827 |
4813 #endif // V8_TARGET_ARCH_X64 | 4828 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |