OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
623 if (false_label_ != fall_through_) __ jmp(false_label_); | 623 if (false_label_ != fall_through_) __ jmp(false_label_); |
624 } | 624 } |
625 } | 625 } |
626 | 626 |
627 | 627 |
628 void FullCodeGenerator::DoTest(Expression* condition, | 628 void FullCodeGenerator::DoTest(Expression* condition, |
629 Label* if_true, | 629 Label* if_true, |
630 Label* if_false, | 630 Label* if_false, |
631 Label* fall_through) { | 631 Label* fall_through) { |
632 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); | 632 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); |
633 CallIC(ic, RelocInfo::CODE_TARGET, condition->test_id()); | 633 CallIC(ic, NOT_CONTEXTUAL, condition->test_id()); |
634 __ testq(result_register(), result_register()); | 634 __ testq(result_register(), result_register()); |
635 // The stub returns nonzero for true. | 635 // The stub returns nonzero for true. |
636 Split(not_zero, if_true, if_false, fall_through); | 636 Split(not_zero, if_true, if_false, fall_through); |
637 } | 637 } |
638 | 638 |
639 | 639 |
640 void FullCodeGenerator::Split(Condition cc, | 640 void FullCodeGenerator::Split(Condition cc, |
641 Label* if_true, | 641 Label* if_true, |
642 Label* if_false, | 642 Label* if_false, |
643 Label* fall_through) { | 643 Label* fall_through) { |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
976 __ cmpq(rdx, rax); | 976 __ cmpq(rdx, rax); |
977 __ j(not_equal, &next_test); | 977 __ j(not_equal, &next_test); |
978 __ Drop(1); // Switch value is no longer needed. | 978 __ Drop(1); // Switch value is no longer needed. |
979 __ jmp(clause->body_target()); | 979 __ jmp(clause->body_target()); |
980 __ bind(&slow_case); | 980 __ bind(&slow_case); |
981 } | 981 } |
982 | 982 |
983 // Record position before stub call for type feedback. | 983 // Record position before stub call for type feedback. |
984 SetSourcePosition(clause->position()); | 984 SetSourcePosition(clause->position()); |
985 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); | 985 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); |
986 CallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId()); | 986 CallIC(ic, NOT_CONTEXTUAL, clause->CompareId()); |
987 patch_site.EmitPatchInfo(); | 987 patch_site.EmitPatchInfo(); |
988 | 988 |
989 __ testq(rax, rax); | 989 __ testq(rax, rax); |
990 __ j(not_equal, &next_test); | 990 __ j(not_equal, &next_test); |
991 __ Drop(1); // Switch value is no longer needed. | 991 __ Drop(1); // Switch value is no longer needed. |
992 __ jmp(clause->body_target()); | 992 __ jmp(clause->body_target()); |
993 } | 993 } |
994 | 994 |
995 // Discard the test value and jump to the default if present, otherwise to | 995 // Discard the test value and jump to the default if present, otherwise to |
996 // the end of the statement. | 996 // the end of the statement. |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1337 // Load next context in chain. | 1337 // Load next context in chain. |
1338 __ movq(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); | 1338 __ movq(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); |
1339 __ jmp(&next); | 1339 __ jmp(&next); |
1340 __ bind(&fast); | 1340 __ bind(&fast); |
1341 } | 1341 } |
1342 | 1342 |
1343 // All extension objects were empty and it is safe to use a global | 1343 // All extension objects were empty and it is safe to use a global |
1344 // load IC call. | 1344 // load IC call. |
1345 __ movq(rax, GlobalObjectOperand()); | 1345 __ movq(rax, GlobalObjectOperand()); |
1346 __ Move(rcx, var->name()); | 1346 __ Move(rcx, var->name()); |
1347 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1347 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) |
1348 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 1348 ? NOT_CONTEXTUAL |
1349 ? RelocInfo::CODE_TARGET | 1349 : CONTEXTUAL; |
1350 : RelocInfo::CODE_TARGET_CONTEXT; | 1350 CallLoadIC(mode); |
1351 CallIC(ic, mode); | |
1352 } | 1351 } |
1353 | 1352 |
1354 | 1353 |
1355 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1354 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
1356 Label* slow) { | 1355 Label* slow) { |
1357 ASSERT(var->IsContextSlot()); | 1356 ASSERT(var->IsContextSlot()); |
1358 Register context = rsi; | 1357 Register context = rsi; |
1359 Register temp = rbx; | 1358 Register temp = rbx; |
1360 | 1359 |
1361 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { | 1360 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1421 | 1420 |
1422 // Three cases: global variables, lookup variables, and all other types of | 1421 // Three cases: global variables, lookup variables, and all other types of |
1423 // variables. | 1422 // variables. |
1424 switch (var->location()) { | 1423 switch (var->location()) { |
1425 case Variable::UNALLOCATED: { | 1424 case Variable::UNALLOCATED: { |
1426 Comment cmnt(masm_, "Global variable"); | 1425 Comment cmnt(masm_, "Global variable"); |
1427 // Use inline caching. Variable name is passed in rcx and the global | 1426 // Use inline caching. Variable name is passed in rcx and the global |
1428 // object on the stack. | 1427 // object on the stack. |
1429 __ Move(rcx, var->name()); | 1428 __ Move(rcx, var->name()); |
1430 __ movq(rax, GlobalObjectOperand()); | 1429 __ movq(rax, GlobalObjectOperand()); |
1431 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1430 CallLoadIC(CONTEXTUAL); |
1432 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | |
1433 context()->Plug(rax); | 1431 context()->Plug(rax); |
1434 break; | 1432 break; |
1435 } | 1433 } |
1436 | 1434 |
1437 case Variable::PARAMETER: | 1435 case Variable::PARAMETER: |
1438 case Variable::LOCAL: | 1436 case Variable::LOCAL: |
1439 case Variable::CONTEXT: { | 1437 case Variable::CONTEXT: { |
1440 Comment cmnt(masm_, var->IsContextSlot() ? "Context slot" : "Stack slot"); | 1438 Comment cmnt(masm_, var->IsContextSlot() ? "Context slot" : "Stack slot"); |
1441 if (var->binding_needs_init()) { | 1439 if (var->binding_needs_init()) { |
1442 // var->scope() may be NULL when the proxy is located in eval code and | 1440 // var->scope() may be NULL when the proxy is located in eval code and |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1636 UNREACHABLE(); | 1634 UNREACHABLE(); |
1637 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1635 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1638 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); | 1636 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); |
1639 // Fall through. | 1637 // Fall through. |
1640 case ObjectLiteral::Property::COMPUTED: | 1638 case ObjectLiteral::Property::COMPUTED: |
1641 if (key->value()->IsInternalizedString()) { | 1639 if (key->value()->IsInternalizedString()) { |
1642 if (property->emit_store()) { | 1640 if (property->emit_store()) { |
1643 VisitForAccumulatorValue(value); | 1641 VisitForAccumulatorValue(value); |
1644 __ Move(rcx, key->value()); | 1642 __ Move(rcx, key->value()); |
1645 __ movq(rdx, Operand(rsp, 0)); | 1643 __ movq(rdx, Operand(rsp, 0)); |
1646 Handle<Code> ic = is_classic_mode() | 1644 CallStoreIC(NOT_CONTEXTUAL, key->LiteralFeedbackId()); |
1647 ? isolate()->builtins()->StoreIC_Initialize() | |
1648 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
1649 CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId()); | |
1650 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1645 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
1651 } else { | 1646 } else { |
1652 VisitForEffect(value); | 1647 VisitForEffect(value); |
1653 } | 1648 } |
1654 break; | 1649 break; |
1655 } | 1650 } |
1656 __ push(Operand(rsp, 0)); // Duplicate receiver. | 1651 __ push(Operand(rsp, 0)); // Duplicate receiver. |
1657 VisitForStackValue(key); | 1652 VisitForStackValue(key); |
1658 VisitForStackValue(value); | 1653 VisitForStackValue(value); |
1659 if (property->emit_store()) { | 1654 if (property->emit_store()) { |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2061 __ bind(&l_call); | 2056 __ bind(&l_call); |
2062 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); | 2057 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); |
2063 CallIC(ic); | 2058 CallIC(ic); |
2064 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2059 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2065 __ Drop(1); // The key is still on the stack; drop it. | 2060 __ Drop(1); // The key is still on the stack; drop it. |
2066 | 2061 |
2067 // if (!result.done) goto l_try; | 2062 // if (!result.done) goto l_try; |
2068 __ bind(&l_loop); | 2063 __ bind(&l_loop); |
2069 __ push(rax); // save result | 2064 __ push(rax); // save result |
2070 __ LoadRoot(rcx, Heap::kdone_stringRootIndex); // "done" | 2065 __ LoadRoot(rcx, Heap::kdone_stringRootIndex); // "done" |
2071 Handle<Code> done_ic = isolate()->builtins()->LoadIC_Initialize(); | 2066 CallLoadIC(NOT_CONTEXTUAL); // result.done in rax |
2072 CallIC(done_ic); // result.done in rax | |
2073 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); | 2067 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); |
2074 CallIC(bool_ic); | 2068 CallIC(bool_ic); |
2075 __ testq(result_register(), result_register()); | 2069 __ testq(result_register(), result_register()); |
2076 __ j(zero, &l_try); | 2070 __ j(zero, &l_try); |
2077 | 2071 |
2078 // result.value | 2072 // result.value |
2079 __ pop(rax); // result | 2073 __ pop(rax); // result |
2080 __ LoadRoot(rcx, Heap::kvalue_stringRootIndex); // "value" | 2074 __ LoadRoot(rcx, Heap::kvalue_stringRootIndex); // "value" |
2081 Handle<Code> value_ic = isolate()->builtins()->LoadIC_Initialize(); | 2075 CallLoadIC(NOT_CONTEXTUAL); // result.value in rax |
2082 CallIC(value_ic); // result.value in rax | |
2083 context()->DropAndPlug(2, rax); // drop iter and g | 2076 context()->DropAndPlug(2, rax); // drop iter and g |
2084 break; | 2077 break; |
2085 } | 2078 } |
2086 } | 2079 } |
2087 } | 2080 } |
2088 | 2081 |
2089 | 2082 |
2090 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 2083 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
2091 Expression *value, | 2084 Expression *value, |
2092 JSGeneratorObject::ResumeMode resume_mode) { | 2085 JSGeneratorObject::ResumeMode resume_mode) { |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2218 // root set. | 2211 // root set. |
2219 __ RecordWriteField(rax, JSGeneratorObject::kResultValuePropertyOffset, | 2212 __ RecordWriteField(rax, JSGeneratorObject::kResultValuePropertyOffset, |
2220 rcx, rdx, kDontSaveFPRegs); | 2213 rcx, rdx, kDontSaveFPRegs); |
2221 } | 2214 } |
2222 | 2215 |
2223 | 2216 |
2224 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2217 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
2225 SetSourcePosition(prop->position()); | 2218 SetSourcePosition(prop->position()); |
2226 Literal* key = prop->key()->AsLiteral(); | 2219 Literal* key = prop->key()->AsLiteral(); |
2227 __ Move(rcx, key->value()); | 2220 __ Move(rcx, key->value()); |
2228 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 2221 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
2229 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); | |
2230 } | 2222 } |
2231 | 2223 |
2232 | 2224 |
2233 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2225 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
2234 SetSourcePosition(prop->position()); | 2226 SetSourcePosition(prop->position()); |
2235 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2227 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
2236 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); | 2228 CallIC(ic, NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
2237 } | 2229 } |
2238 | 2230 |
2239 | 2231 |
2240 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2232 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
2241 Token::Value op, | 2233 Token::Value op, |
2242 OverwriteMode mode, | 2234 OverwriteMode mode, |
2243 Expression* left, | 2235 Expression* left, |
2244 Expression* right) { | 2236 Expression* right) { |
2245 // Do combined smi check of the operands. Left operand is on the | 2237 // Do combined smi check of the operands. Left operand is on the |
2246 // stack (popped into rdx). Right operand is in rax but moved into | 2238 // stack (popped into rdx). Right operand is in rax but moved into |
2247 // rcx to make the shifts easier. | 2239 // rcx to make the shifts easier. |
2248 Label done, stub_call, smi_case; | 2240 Label done, stub_call, smi_case; |
2249 __ pop(rdx); | 2241 __ pop(rdx); |
2250 __ movq(rcx, rax); | 2242 __ movq(rcx, rax); |
2251 __ or_(rax, rdx); | 2243 __ or_(rax, rdx); |
2252 JumpPatchSite patch_site(masm_); | 2244 JumpPatchSite patch_site(masm_); |
2253 patch_site.EmitJumpIfSmi(rax, &smi_case, Label::kNear); | 2245 patch_site.EmitJumpIfSmi(rax, &smi_case, Label::kNear); |
2254 | 2246 |
2255 __ bind(&stub_call); | 2247 __ bind(&stub_call); |
2256 __ movq(rax, rcx); | 2248 __ movq(rax, rcx); |
2257 BinaryOpICStub stub(op, mode); | 2249 BinaryOpICStub stub(op, mode); |
2258 CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, | 2250 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, |
2259 expr->BinaryOperationFeedbackId()); | 2251 expr->BinaryOperationFeedbackId()); |
2260 patch_site.EmitPatchInfo(); | 2252 patch_site.EmitPatchInfo(); |
2261 __ jmp(&done, Label::kNear); | 2253 __ jmp(&done, Label::kNear); |
2262 | 2254 |
2263 __ bind(&smi_case); | 2255 __ bind(&smi_case); |
2264 switch (op) { | 2256 switch (op) { |
2265 case Token::SAR: | 2257 case Token::SAR: |
2266 __ SmiShiftArithmeticRight(rax, rdx, rcx); | 2258 __ SmiShiftArithmeticRight(rax, rdx, rcx); |
2267 break; | 2259 break; |
2268 case Token::SHL: | 2260 case Token::SHL: |
(...skipping 29 matching lines...) Expand all Loading... |
2298 context()->Plug(rax); | 2290 context()->Plug(rax); |
2299 } | 2291 } |
2300 | 2292 |
2301 | 2293 |
2302 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 2294 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
2303 Token::Value op, | 2295 Token::Value op, |
2304 OverwriteMode mode) { | 2296 OverwriteMode mode) { |
2305 __ pop(rdx); | 2297 __ pop(rdx); |
2306 BinaryOpICStub stub(op, mode); | 2298 BinaryOpICStub stub(op, mode); |
2307 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2299 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
2308 CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, | 2300 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, |
2309 expr->BinaryOperationFeedbackId()); | 2301 expr->BinaryOperationFeedbackId()); |
2310 patch_site.EmitPatchInfo(); | 2302 patch_site.EmitPatchInfo(); |
2311 context()->Plug(rax); | 2303 context()->Plug(rax); |
2312 } | 2304 } |
2313 | 2305 |
2314 | 2306 |
2315 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2307 void FullCodeGenerator::EmitAssignment(Expression* expr) { |
2316 // Invalid left-hand sides are rewritten by the parser to have a 'throw | 2308 // Invalid left-hand sides are rewritten by the parser to have a 'throw |
2317 // ReferenceError' on the left-hand side. | 2309 // ReferenceError' on the left-hand side. |
2318 if (!expr->IsValidLeftHandSide()) { | 2310 if (!expr->IsValidLeftHandSide()) { |
(...skipping 18 matching lines...) Expand all Loading... |
2337 EffectContext context(this); | 2329 EffectContext context(this); |
2338 EmitVariableAssignment(var, Token::ASSIGN); | 2330 EmitVariableAssignment(var, Token::ASSIGN); |
2339 break; | 2331 break; |
2340 } | 2332 } |
2341 case NAMED_PROPERTY: { | 2333 case NAMED_PROPERTY: { |
2342 __ push(rax); // Preserve value. | 2334 __ push(rax); // Preserve value. |
2343 VisitForAccumulatorValue(prop->obj()); | 2335 VisitForAccumulatorValue(prop->obj()); |
2344 __ movq(rdx, rax); | 2336 __ movq(rdx, rax); |
2345 __ pop(rax); // Restore value. | 2337 __ pop(rax); // Restore value. |
2346 __ Move(rcx, prop->key()->AsLiteral()->value()); | 2338 __ Move(rcx, prop->key()->AsLiteral()->value()); |
2347 Handle<Code> ic = is_classic_mode() | 2339 CallStoreIC(NOT_CONTEXTUAL); |
2348 ? isolate()->builtins()->StoreIC_Initialize() | |
2349 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
2350 CallIC(ic); | |
2351 break; | 2340 break; |
2352 } | 2341 } |
2353 case KEYED_PROPERTY: { | 2342 case KEYED_PROPERTY: { |
2354 __ push(rax); // Preserve value. | 2343 __ push(rax); // Preserve value. |
2355 VisitForStackValue(prop->obj()); | 2344 VisitForStackValue(prop->obj()); |
2356 VisitForAccumulatorValue(prop->key()); | 2345 VisitForAccumulatorValue(prop->key()); |
2357 __ movq(rcx, rax); | 2346 __ movq(rcx, rax); |
2358 __ pop(rdx); | 2347 __ pop(rdx); |
2359 __ pop(rax); // Restore value. | 2348 __ pop(rax); // Restore value. |
2360 Handle<Code> ic = is_classic_mode() | 2349 Handle<Code> ic = is_classic_mode() |
2361 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2350 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
2362 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2351 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
2363 CallIC(ic); | 2352 CallIC(ic); |
2364 break; | 2353 break; |
2365 } | 2354 } |
2366 } | 2355 } |
2367 context()->Plug(rax); | 2356 context()->Plug(rax); |
2368 } | 2357 } |
2369 | 2358 |
2370 | 2359 |
2371 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 2360 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
2372 Token::Value op) { | 2361 Token::Value op) { |
2373 if (var->IsUnallocated()) { | 2362 if (var->IsUnallocated()) { |
2374 // Global var, const, or let. | 2363 // Global var, const, or let. |
2375 __ Move(rcx, var->name()); | 2364 __ Move(rcx, var->name()); |
2376 __ movq(rdx, GlobalObjectOperand()); | 2365 __ movq(rdx, GlobalObjectOperand()); |
2377 Handle<Code> ic = is_classic_mode() | 2366 CallStoreIC(CONTEXTUAL); |
2378 ? isolate()->builtins()->StoreIC_Initialize() | |
2379 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
2380 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | |
2381 } else if (op == Token::INIT_CONST) { | 2367 } else if (op == Token::INIT_CONST) { |
2382 // Const initializers need a write barrier. | 2368 // Const initializers need a write barrier. |
2383 ASSERT(!var->IsParameter()); // No const parameters. | 2369 ASSERT(!var->IsParameter()); // No const parameters. |
2384 if (var->IsStackLocal()) { | 2370 if (var->IsStackLocal()) { |
2385 Label skip; | 2371 Label skip; |
2386 __ movq(rdx, StackOperand(var)); | 2372 __ movq(rdx, StackOperand(var)); |
2387 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); | 2373 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); |
2388 __ j(not_equal, &skip); | 2374 __ j(not_equal, &skip); |
2389 __ movq(StackOperand(var), rax); | 2375 __ movq(StackOperand(var), rax); |
2390 __ bind(&skip); | 2376 __ bind(&skip); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2461 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2447 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
2462 // Assignment to a property, using a named store IC. | 2448 // Assignment to a property, using a named store IC. |
2463 Property* prop = expr->target()->AsProperty(); | 2449 Property* prop = expr->target()->AsProperty(); |
2464 ASSERT(prop != NULL); | 2450 ASSERT(prop != NULL); |
2465 ASSERT(prop->key()->AsLiteral() != NULL); | 2451 ASSERT(prop->key()->AsLiteral() != NULL); |
2466 | 2452 |
2467 // Record source code position before IC call. | 2453 // Record source code position before IC call. |
2468 SetSourcePosition(expr->position()); | 2454 SetSourcePosition(expr->position()); |
2469 __ Move(rcx, prop->key()->AsLiteral()->value()); | 2455 __ Move(rcx, prop->key()->AsLiteral()->value()); |
2470 __ pop(rdx); | 2456 __ pop(rdx); |
2471 Handle<Code> ic = is_classic_mode() | 2457 CallStoreIC(NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); |
2472 ? isolate()->builtins()->StoreIC_Initialize() | |
2473 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
2474 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); | |
2475 | 2458 |
2476 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2459 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2477 context()->Plug(rax); | 2460 context()->Plug(rax); |
2478 } | 2461 } |
2479 | 2462 |
2480 | 2463 |
2481 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2464 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2482 // Assignment to a property, using a keyed store IC. | 2465 // Assignment to a property, using a keyed store IC. |
2483 | 2466 |
2484 __ pop(rcx); | 2467 __ pop(rcx); |
2485 __ pop(rdx); | 2468 __ pop(rdx); |
2486 // Record source code position before IC call. | 2469 // Record source code position before IC call. |
2487 SetSourcePosition(expr->position()); | 2470 SetSourcePosition(expr->position()); |
2488 Handle<Code> ic = is_classic_mode() | 2471 Handle<Code> ic = is_classic_mode() |
2489 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2472 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
2490 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2473 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
2491 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); | 2474 CallIC(ic, NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); |
2492 | 2475 |
2493 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2476 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2494 context()->Plug(rax); | 2477 context()->Plug(rax); |
2495 } | 2478 } |
2496 | 2479 |
2497 | 2480 |
2498 void FullCodeGenerator::VisitProperty(Property* expr) { | 2481 void FullCodeGenerator::VisitProperty(Property* expr) { |
2499 Comment cmnt(masm_, "[ Property"); | 2482 Comment cmnt(masm_, "[ Property"); |
2500 Expression* key = expr->key(); | 2483 Expression* key = expr->key(); |
2501 | 2484 |
2502 if (key->IsPropertyName()) { | 2485 if (key->IsPropertyName()) { |
2503 VisitForAccumulatorValue(expr->obj()); | 2486 VisitForAccumulatorValue(expr->obj()); |
2504 EmitNamedPropertyLoad(expr); | 2487 EmitNamedPropertyLoad(expr); |
2505 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2488 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
2506 context()->Plug(rax); | 2489 context()->Plug(rax); |
2507 } else { | 2490 } else { |
2508 VisitForStackValue(expr->obj()); | 2491 VisitForStackValue(expr->obj()); |
2509 VisitForAccumulatorValue(expr->key()); | 2492 VisitForAccumulatorValue(expr->key()); |
2510 __ pop(rdx); | 2493 __ pop(rdx); |
2511 EmitKeyedPropertyLoad(expr); | 2494 EmitKeyedPropertyLoad(expr); |
2512 context()->Plug(rax); | 2495 context()->Plug(rax); |
2513 } | 2496 } |
2514 } | 2497 } |
2515 | 2498 |
2516 | 2499 |
2517 void FullCodeGenerator::CallIC(Handle<Code> code, | 2500 void FullCodeGenerator::CallIC(Handle<Code> code, |
2518 RelocInfo::Mode rmode, | 2501 ContextualMode mode, |
2519 TypeFeedbackId ast_id) { | 2502 TypeFeedbackId ast_id) { |
2520 ic_total_count_++; | 2503 ic_total_count_++; |
2521 __ call(code, rmode, ast_id); | 2504 ASSERT(mode != CONTEXTUAL || ast_id.IsNone()); |
| 2505 __ call(code, RelocInfo::CODE_TARGET, ast_id); |
2522 } | 2506 } |
2523 | 2507 |
2524 | 2508 |
2525 void FullCodeGenerator::EmitCallWithIC(Call* expr, | 2509 void FullCodeGenerator::EmitCallWithIC(Call* expr, |
2526 Handle<Object> name, | 2510 Handle<Object> name, |
2527 RelocInfo::Mode mode) { | 2511 ContextualMode mode) { |
2528 // Code common for calls using the IC. | 2512 // Code common for calls using the IC. |
2529 ZoneList<Expression*>* args = expr->arguments(); | 2513 ZoneList<Expression*>* args = expr->arguments(); |
2530 int arg_count = args->length(); | 2514 int arg_count = args->length(); |
2531 { PreservePositionScope scope(masm()->positions_recorder()); | 2515 { PreservePositionScope scope(masm()->positions_recorder()); |
2532 for (int i = 0; i < arg_count; i++) { | 2516 for (int i = 0; i < arg_count; i++) { |
2533 VisitForStackValue(args->at(i)); | 2517 VisitForStackValue(args->at(i)); |
2534 } | 2518 } |
2535 __ Move(rcx, name); | 2519 __ Move(rcx, name); |
2536 } | 2520 } |
2537 // Record source position for debugger. | 2521 // Record source position for debugger. |
2538 SetSourcePosition(expr->position()); | 2522 SetSourcePosition(expr->position()); |
2539 // Call the IC initialization code. | 2523 // Call the IC initialization code. |
2540 Handle<Code> ic = | 2524 Handle<Code> ic = |
2541 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 2525 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
2542 CallIC(ic, mode, expr->CallFeedbackId()); | 2526 TypeFeedbackId ast_id = mode == CONTEXTUAL |
| 2527 ? TypeFeedbackId::None() |
| 2528 : expr->CallFeedbackId(); |
| 2529 CallIC(ic, mode, ast_id); |
2543 RecordJSReturnSite(expr); | 2530 RecordJSReturnSite(expr); |
2544 // Restore context register. | 2531 // Restore context register. |
2545 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2532 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2546 context()->Plug(rax); | 2533 context()->Plug(rax); |
2547 } | 2534 } |
2548 | 2535 |
2549 | 2536 |
2550 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2537 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
2551 Expression* key) { | 2538 Expression* key) { |
2552 // Load the key. | 2539 // Load the key. |
(...skipping 12 matching lines...) Expand all Loading... |
2565 for (int i = 0; i < arg_count; i++) { | 2552 for (int i = 0; i < arg_count; i++) { |
2566 VisitForStackValue(args->at(i)); | 2553 VisitForStackValue(args->at(i)); |
2567 } | 2554 } |
2568 } | 2555 } |
2569 // Record source position for debugger. | 2556 // Record source position for debugger. |
2570 SetSourcePosition(expr->position()); | 2557 SetSourcePosition(expr->position()); |
2571 // Call the IC initialization code. | 2558 // Call the IC initialization code. |
2572 Handle<Code> ic = | 2559 Handle<Code> ic = |
2573 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); | 2560 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); |
2574 __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key. | 2561 __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key. |
2575 CallIC(ic, RelocInfo::CODE_TARGET, expr->CallFeedbackId()); | 2562 CallIC(ic, NOT_CONTEXTUAL, expr->CallFeedbackId()); |
2576 RecordJSReturnSite(expr); | 2563 RecordJSReturnSite(expr); |
2577 // Restore context register. | 2564 // Restore context register. |
2578 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2565 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2579 context()->DropAndPlug(1, rax); // Drop the key still on the stack. | 2566 context()->DropAndPlug(1, rax); // Drop the key still on the stack. |
2580 } | 2567 } |
2581 | 2568 |
2582 | 2569 |
2583 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { | 2570 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { |
2584 // Code common for calls using the call stub. | 2571 // Code common for calls using the call stub. |
2585 ZoneList<Expression*>* args = expr->arguments(); | 2572 ZoneList<Expression*>* args = expr->arguments(); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2677 __ movq(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 2664 __ movq(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |
2678 __ CallStub(&stub); | 2665 __ CallStub(&stub); |
2679 RecordJSReturnSite(expr); | 2666 RecordJSReturnSite(expr); |
2680 // Restore context register. | 2667 // Restore context register. |
2681 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2668 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2682 context()->DropAndPlug(1, rax); | 2669 context()->DropAndPlug(1, rax); |
2683 } else if (proxy != NULL && proxy->var()->IsUnallocated()) { | 2670 } else if (proxy != NULL && proxy->var()->IsUnallocated()) { |
2684 // Call to a global variable. Push global object as receiver for the | 2671 // Call to a global variable. Push global object as receiver for the |
2685 // call IC lookup. | 2672 // call IC lookup. |
2686 __ push(GlobalObjectOperand()); | 2673 __ push(GlobalObjectOperand()); |
2687 EmitCallWithIC(expr, proxy->name(), RelocInfo::CODE_TARGET_CONTEXT); | 2674 EmitCallWithIC(expr, proxy->name(), CONTEXTUAL); |
2688 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 2675 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
2689 // Call to a lookup slot (dynamically introduced variable). | 2676 // Call to a lookup slot (dynamically introduced variable). |
2690 Label slow, done; | 2677 Label slow, done; |
2691 | 2678 |
2692 { PreservePositionScope scope(masm()->positions_recorder()); | 2679 { PreservePositionScope scope(masm()->positions_recorder()); |
2693 // Generate code for loading from variables potentially shadowed by | 2680 // Generate code for loading from variables potentially shadowed by |
2694 // eval-introduced variables. | 2681 // eval-introduced variables. |
2695 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); | 2682 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); |
2696 } | 2683 } |
2697 __ bind(&slow); | 2684 __ bind(&slow); |
(...skipping 23 matching lines...) Expand all Loading... |
2721 // LoadContextSlot. That object could be the hole if the receiver is | 2708 // LoadContextSlot. That object could be the hole if the receiver is |
2722 // implicitly the global object. | 2709 // implicitly the global object. |
2723 EmitCallWithStub(expr, RECEIVER_MIGHT_BE_IMPLICIT); | 2710 EmitCallWithStub(expr, RECEIVER_MIGHT_BE_IMPLICIT); |
2724 } else if (property != NULL) { | 2711 } else if (property != NULL) { |
2725 { PreservePositionScope scope(masm()->positions_recorder()); | 2712 { PreservePositionScope scope(masm()->positions_recorder()); |
2726 VisitForStackValue(property->obj()); | 2713 VisitForStackValue(property->obj()); |
2727 } | 2714 } |
2728 if (property->key()->IsPropertyName()) { | 2715 if (property->key()->IsPropertyName()) { |
2729 EmitCallWithIC(expr, | 2716 EmitCallWithIC(expr, |
2730 property->key()->AsLiteral()->value(), | 2717 property->key()->AsLiteral()->value(), |
2731 RelocInfo::CODE_TARGET); | 2718 NOT_CONTEXTUAL); |
2732 } else { | 2719 } else { |
2733 EmitKeyedCallWithIC(expr, property->key()); | 2720 EmitKeyedCallWithIC(expr, property->key()); |
2734 } | 2721 } |
2735 } else { | 2722 } else { |
2736 // Call to an arbitrary expression not handled specially above. | 2723 // Call to an arbitrary expression not handled specially above. |
2737 { PreservePositionScope scope(masm()->positions_recorder()); | 2724 { PreservePositionScope scope(masm()->positions_recorder()); |
2738 VisitForStackValue(callee); | 2725 VisitForStackValue(callee); |
2739 } | 2726 } |
2740 // Load global receiver object. | 2727 // Load global receiver object. |
2741 __ movq(rbx, GlobalObjectOperand()); | 2728 __ movq(rbx, GlobalObjectOperand()); |
(...skipping 1390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4132 | 4119 |
4133 // Push the arguments ("left-to-right"). | 4120 // Push the arguments ("left-to-right"). |
4134 int arg_count = args->length(); | 4121 int arg_count = args->length(); |
4135 for (int i = 0; i < arg_count; i++) { | 4122 for (int i = 0; i < arg_count; i++) { |
4136 VisitForStackValue(args->at(i)); | 4123 VisitForStackValue(args->at(i)); |
4137 } | 4124 } |
4138 | 4125 |
4139 if (expr->is_jsruntime()) { | 4126 if (expr->is_jsruntime()) { |
4140 // Call the JS runtime function using a call IC. | 4127 // Call the JS runtime function using a call IC. |
4141 __ Move(rcx, expr->name()); | 4128 __ Move(rcx, expr->name()); |
4142 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; | 4129 ContextualMode mode = NOT_CONTEXTUAL; |
4143 Handle<Code> ic = | 4130 Handle<Code> ic = |
4144 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 4131 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
4145 CallIC(ic, mode, expr->CallRuntimeFeedbackId()); | 4132 CallIC(ic, mode, expr->CallRuntimeFeedbackId()); |
4146 // Restore context register. | 4133 // Restore context register. |
4147 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 4134 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
4148 } else { | 4135 } else { |
4149 __ CallRuntime(expr->function(), arg_count); | 4136 __ CallRuntime(expr->function(), arg_count); |
4150 } | 4137 } |
4151 context()->Plug(rax); | 4138 context()->Plug(rax); |
4152 } | 4139 } |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4386 | 4373 |
4387 // Record position before stub call. | 4374 // Record position before stub call. |
4388 SetSourcePosition(expr->position()); | 4375 SetSourcePosition(expr->position()); |
4389 | 4376 |
4390 // Call stub for +1/-1. | 4377 // Call stub for +1/-1. |
4391 __ bind(&stub_call); | 4378 __ bind(&stub_call); |
4392 __ movq(rdx, rax); | 4379 __ movq(rdx, rax); |
4393 __ Move(rax, Smi::FromInt(1)); | 4380 __ Move(rax, Smi::FromInt(1)); |
4394 BinaryOpICStub stub(expr->binary_op(), NO_OVERWRITE); | 4381 BinaryOpICStub stub(expr->binary_op(), NO_OVERWRITE); |
4395 CallIC(stub.GetCode(isolate()), | 4382 CallIC(stub.GetCode(isolate()), |
4396 RelocInfo::CODE_TARGET, | 4383 NOT_CONTEXTUAL, |
4397 expr->CountBinOpFeedbackId()); | 4384 expr->CountBinOpFeedbackId()); |
4398 patch_site.EmitPatchInfo(); | 4385 patch_site.EmitPatchInfo(); |
4399 __ bind(&done); | 4386 __ bind(&done); |
4400 | 4387 |
4401 // Store the value returned in rax. | 4388 // Store the value returned in rax. |
4402 switch (assign_type) { | 4389 switch (assign_type) { |
4403 case VARIABLE: | 4390 case VARIABLE: |
4404 if (expr->is_postfix()) { | 4391 if (expr->is_postfix()) { |
4405 // Perform the assignment as if via '='. | 4392 // Perform the assignment as if via '='. |
4406 { EffectContext context(this); | 4393 { EffectContext context(this); |
(...skipping 11 matching lines...) Expand all Loading... |
4418 // Perform the assignment as if via '='. | 4405 // Perform the assignment as if via '='. |
4419 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4406 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
4420 Token::ASSIGN); | 4407 Token::ASSIGN); |
4421 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4408 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4422 context()->Plug(rax); | 4409 context()->Plug(rax); |
4423 } | 4410 } |
4424 break; | 4411 break; |
4425 case NAMED_PROPERTY: { | 4412 case NAMED_PROPERTY: { |
4426 __ Move(rcx, prop->key()->AsLiteral()->value()); | 4413 __ Move(rcx, prop->key()->AsLiteral()->value()); |
4427 __ pop(rdx); | 4414 __ pop(rdx); |
4428 Handle<Code> ic = is_classic_mode() | 4415 CallStoreIC(NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); |
4429 ? isolate()->builtins()->StoreIC_Initialize() | |
4430 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
4431 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); | |
4432 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4416 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4433 if (expr->is_postfix()) { | 4417 if (expr->is_postfix()) { |
4434 if (!context()->IsEffect()) { | 4418 if (!context()->IsEffect()) { |
4435 context()->PlugTOS(); | 4419 context()->PlugTOS(); |
4436 } | 4420 } |
4437 } else { | 4421 } else { |
4438 context()->Plug(rax); | 4422 context()->Plug(rax); |
4439 } | 4423 } |
4440 break; | 4424 break; |
4441 } | 4425 } |
4442 case KEYED_PROPERTY: { | 4426 case KEYED_PROPERTY: { |
4443 __ pop(rcx); | 4427 __ pop(rcx); |
4444 __ pop(rdx); | 4428 __ pop(rdx); |
4445 Handle<Code> ic = is_classic_mode() | 4429 Handle<Code> ic = is_classic_mode() |
4446 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 4430 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
4447 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 4431 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
4448 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); | 4432 CallIC(ic, NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); |
4449 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4433 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4450 if (expr->is_postfix()) { | 4434 if (expr->is_postfix()) { |
4451 if (!context()->IsEffect()) { | 4435 if (!context()->IsEffect()) { |
4452 context()->PlugTOS(); | 4436 context()->PlugTOS(); |
4453 } | 4437 } |
4454 } else { | 4438 } else { |
4455 context()->Plug(rax); | 4439 context()->Plug(rax); |
4456 } | 4440 } |
4457 break; | 4441 break; |
4458 } | 4442 } |
4459 } | 4443 } |
4460 } | 4444 } |
4461 | 4445 |
4462 | 4446 |
4463 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 4447 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
4464 VariableProxy* proxy = expr->AsVariableProxy(); | 4448 VariableProxy* proxy = expr->AsVariableProxy(); |
4465 ASSERT(!context()->IsEffect()); | 4449 ASSERT(!context()->IsEffect()); |
4466 ASSERT(!context()->IsTest()); | 4450 ASSERT(!context()->IsTest()); |
4467 | 4451 |
4468 if (proxy != NULL && proxy->var()->IsUnallocated()) { | 4452 if (proxy != NULL && proxy->var()->IsUnallocated()) { |
4469 Comment cmnt(masm_, "Global variable"); | 4453 Comment cmnt(masm_, "Global variable"); |
4470 __ Move(rcx, proxy->name()); | 4454 __ Move(rcx, proxy->name()); |
4471 __ movq(rax, GlobalObjectOperand()); | 4455 __ movq(rax, GlobalObjectOperand()); |
4472 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | |
4473 // Use a regular load, not a contextual load, to avoid a reference | 4456 // Use a regular load, not a contextual load, to avoid a reference |
4474 // error. | 4457 // error. |
4475 CallIC(ic); | 4458 CallLoadIC(NOT_CONTEXTUAL); |
4476 PrepareForBailout(expr, TOS_REG); | 4459 PrepareForBailout(expr, TOS_REG); |
4477 context()->Plug(rax); | 4460 context()->Plug(rax); |
4478 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 4461 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
4479 Label done, slow; | 4462 Label done, slow; |
4480 | 4463 |
4481 // Generate code for loading from variables potentially shadowed | 4464 // Generate code for loading from variables potentially shadowed |
4482 // by eval-introduced variables. | 4465 // by eval-introduced variables. |
4483 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); | 4466 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); |
4484 | 4467 |
4485 __ bind(&slow); | 4468 __ bind(&slow); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4627 __ or_(rcx, rax); | 4610 __ or_(rcx, rax); |
4628 patch_site.EmitJumpIfNotSmi(rcx, &slow_case, Label::kNear); | 4611 patch_site.EmitJumpIfNotSmi(rcx, &slow_case, Label::kNear); |
4629 __ cmpq(rdx, rax); | 4612 __ cmpq(rdx, rax); |
4630 Split(cc, if_true, if_false, NULL); | 4613 Split(cc, if_true, if_false, NULL); |
4631 __ bind(&slow_case); | 4614 __ bind(&slow_case); |
4632 } | 4615 } |
4633 | 4616 |
4634 // Record position and call the compare IC. | 4617 // Record position and call the compare IC. |
4635 SetSourcePosition(expr->position()); | 4618 SetSourcePosition(expr->position()); |
4636 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); | 4619 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); |
4637 CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); | 4620 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); |
4638 patch_site.EmitPatchInfo(); | 4621 patch_site.EmitPatchInfo(); |
4639 | 4622 |
4640 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4623 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
4641 __ testq(rax, rax); | 4624 __ testq(rax, rax); |
4642 Split(cc, if_true, if_false, fall_through); | 4625 Split(cc, if_true, if_false, fall_through); |
4643 } | 4626 } |
4644 } | 4627 } |
4645 | 4628 |
4646 // Convert the result of the comparison into one expected for this | 4629 // Convert the result of the comparison into one expected for this |
4647 // expression's context. | 4630 // expression's context. |
(...skipping 14 matching lines...) Expand all Loading... |
4662 VisitForAccumulatorValue(sub_expr); | 4645 VisitForAccumulatorValue(sub_expr); |
4663 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4646 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
4664 if (expr->op() == Token::EQ_STRICT) { | 4647 if (expr->op() == Token::EQ_STRICT) { |
4665 Heap::RootListIndex nil_value = nil == kNullValue ? | 4648 Heap::RootListIndex nil_value = nil == kNullValue ? |
4666 Heap::kNullValueRootIndex : | 4649 Heap::kNullValueRootIndex : |
4667 Heap::kUndefinedValueRootIndex; | 4650 Heap::kUndefinedValueRootIndex; |
4668 __ CompareRoot(rax, nil_value); | 4651 __ CompareRoot(rax, nil_value); |
4669 Split(equal, if_true, if_false, fall_through); | 4652 Split(equal, if_true, if_false, fall_through); |
4670 } else { | 4653 } else { |
4671 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); | 4654 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); |
4672 CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); | 4655 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); |
4673 __ testq(rax, rax); | 4656 __ testq(rax, rax); |
4674 Split(not_zero, if_true, if_false, fall_through); | 4657 Split(not_zero, if_true, if_false, fall_through); |
4675 } | 4658 } |
4676 context()->Plug(if_true, if_false); | 4659 context()->Plug(if_true, if_false); |
4677 } | 4660 } |
4678 | 4661 |
4679 | 4662 |
4680 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { | 4663 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { |
4681 __ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 4664 __ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
4682 context()->Plug(rax); | 4665 context()->Plug(rax); |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4894 | 4877 |
4895 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4878 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
4896 Assembler::target_address_at(call_target_address)); | 4879 Assembler::target_address_at(call_target_address)); |
4897 return OSR_AFTER_STACK_CHECK; | 4880 return OSR_AFTER_STACK_CHECK; |
4898 } | 4881 } |
4899 | 4882 |
4900 | 4883 |
4901 } } // namespace v8::internal | 4884 } } // namespace v8::internal |
4902 | 4885 |
4903 #endif // V8_TARGET_ARCH_X64 | 4886 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |