| 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 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 637 if (false_label_ != fall_through_) __ jmp(false_label_); | 637 if (false_label_ != fall_through_) __ jmp(false_label_); |
| 638 } | 638 } |
| 639 } | 639 } |
| 640 | 640 |
| 641 | 641 |
| 642 void FullCodeGenerator::DoTest(Expression* condition, | 642 void FullCodeGenerator::DoTest(Expression* condition, |
| 643 Label* if_true, | 643 Label* if_true, |
| 644 Label* if_false, | 644 Label* if_false, |
| 645 Label* fall_through) { | 645 Label* fall_through) { |
| 646 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); | 646 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); |
| 647 CallIC(ic, RelocInfo::CODE_TARGET, condition->test_id()); | 647 CallIC(ic, NOT_CONTEXTUAL, condition->test_id()); |
| 648 __ testq(result_register(), result_register()); | 648 __ testq(result_register(), result_register()); |
| 649 // The stub returns nonzero for true. | 649 // The stub returns nonzero for true. |
| 650 Split(not_zero, if_true, if_false, fall_through); | 650 Split(not_zero, if_true, if_false, fall_through); |
| 651 } | 651 } |
| 652 | 652 |
| 653 | 653 |
| 654 void FullCodeGenerator::Split(Condition cc, | 654 void FullCodeGenerator::Split(Condition cc, |
| 655 Label* if_true, | 655 Label* if_true, |
| 656 Label* if_false, | 656 Label* if_false, |
| 657 Label* fall_through) { | 657 Label* fall_through) { |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 990 __ cmpq(rdx, rax); | 990 __ cmpq(rdx, rax); |
| 991 __ j(not_equal, &next_test); | 991 __ j(not_equal, &next_test); |
| 992 __ Drop(1); // Switch value is no longer needed. | 992 __ Drop(1); // Switch value is no longer needed. |
| 993 __ jmp(clause->body_target()); | 993 __ jmp(clause->body_target()); |
| 994 __ bind(&slow_case); | 994 __ bind(&slow_case); |
| 995 } | 995 } |
| 996 | 996 |
| 997 // Record position before stub call for type feedback. | 997 // Record position before stub call for type feedback. |
| 998 SetSourcePosition(clause->position()); | 998 SetSourcePosition(clause->position()); |
| 999 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); | 999 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); |
| 1000 CallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId()); | 1000 CallIC(ic, NOT_CONTEXTUAL, clause->CompareId()); |
| 1001 patch_site.EmitPatchInfo(); | 1001 patch_site.EmitPatchInfo(); |
| 1002 | 1002 |
| 1003 __ testq(rax, rax); | 1003 __ testq(rax, rax); |
| 1004 __ j(not_equal, &next_test); | 1004 __ j(not_equal, &next_test); |
| 1005 __ Drop(1); // Switch value is no longer needed. | 1005 __ Drop(1); // Switch value is no longer needed. |
| 1006 __ jmp(clause->body_target()); | 1006 __ jmp(clause->body_target()); |
| 1007 } | 1007 } |
| 1008 | 1008 |
| 1009 // Discard the test value and jump to the default if present, otherwise to | 1009 // Discard the test value and jump to the default if present, otherwise to |
| 1010 // the end of the statement. | 1010 // the end of the statement. |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1351 // Load next context in chain. | 1351 // Load next context in chain. |
| 1352 __ movq(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); | 1352 __ movq(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); |
| 1353 __ jmp(&next); | 1353 __ jmp(&next); |
| 1354 __ bind(&fast); | 1354 __ bind(&fast); |
| 1355 } | 1355 } |
| 1356 | 1356 |
| 1357 // All extension objects were empty and it is safe to use a global | 1357 // All extension objects were empty and it is safe to use a global |
| 1358 // load IC call. | 1358 // load IC call. |
| 1359 __ movq(rax, GlobalObjectOperand()); | 1359 __ movq(rax, GlobalObjectOperand()); |
| 1360 __ Move(rcx, var->name()); | 1360 __ Move(rcx, var->name()); |
| 1361 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1361 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) |
| 1362 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 1362 ? NOT_CONTEXTUAL |
| 1363 ? RelocInfo::CODE_TARGET | 1363 : CONTEXTUAL; |
| 1364 : RelocInfo::CODE_TARGET_CONTEXT; | 1364 CallLoadIC(mode); |
| 1365 CallIC(ic, mode); | |
| 1366 } | 1365 } |
| 1367 | 1366 |
| 1368 | 1367 |
| 1369 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1368 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
| 1370 Label* slow) { | 1369 Label* slow) { |
| 1371 ASSERT(var->IsContextSlot()); | 1370 ASSERT(var->IsContextSlot()); |
| 1372 Register context = rsi; | 1371 Register context = rsi; |
| 1373 Register temp = rbx; | 1372 Register temp = rbx; |
| 1374 | 1373 |
| 1375 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { | 1374 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1435 | 1434 |
| 1436 // Three cases: global variables, lookup variables, and all other types of | 1435 // Three cases: global variables, lookup variables, and all other types of |
| 1437 // variables. | 1436 // variables. |
| 1438 switch (var->location()) { | 1437 switch (var->location()) { |
| 1439 case Variable::UNALLOCATED: { | 1438 case Variable::UNALLOCATED: { |
| 1440 Comment cmnt(masm_, "Global variable"); | 1439 Comment cmnt(masm_, "Global variable"); |
| 1441 // Use inline caching. Variable name is passed in rcx and the global | 1440 // Use inline caching. Variable name is passed in rcx and the global |
| 1442 // object on the stack. | 1441 // object on the stack. |
| 1443 __ Move(rcx, var->name()); | 1442 __ Move(rcx, var->name()); |
| 1444 __ movq(rax, GlobalObjectOperand()); | 1443 __ movq(rax, GlobalObjectOperand()); |
| 1445 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1444 CallLoadIC(CONTEXTUAL); |
| 1446 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | |
| 1447 context()->Plug(rax); | 1445 context()->Plug(rax); |
| 1448 break; | 1446 break; |
| 1449 } | 1447 } |
| 1450 | 1448 |
| 1451 case Variable::PARAMETER: | 1449 case Variable::PARAMETER: |
| 1452 case Variable::LOCAL: | 1450 case Variable::LOCAL: |
| 1453 case Variable::CONTEXT: { | 1451 case Variable::CONTEXT: { |
| 1454 Comment cmnt(masm_, var->IsContextSlot() ? "Context slot" : "Stack slot"); | 1452 Comment cmnt(masm_, var->IsContextSlot() ? "Context slot" : "Stack slot"); |
| 1455 if (var->binding_needs_init()) { | 1453 if (var->binding_needs_init()) { |
| 1456 // var->scope() may be NULL when the proxy is located in eval code and | 1454 // 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... |
| 1650 UNREACHABLE(); | 1648 UNREACHABLE(); |
| 1651 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1649 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1652 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); | 1650 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); |
| 1653 // Fall through. | 1651 // Fall through. |
| 1654 case ObjectLiteral::Property::COMPUTED: | 1652 case ObjectLiteral::Property::COMPUTED: |
| 1655 if (key->value()->IsInternalizedString()) { | 1653 if (key->value()->IsInternalizedString()) { |
| 1656 if (property->emit_store()) { | 1654 if (property->emit_store()) { |
| 1657 VisitForAccumulatorValue(value); | 1655 VisitForAccumulatorValue(value); |
| 1658 __ Move(rcx, key->value()); | 1656 __ Move(rcx, key->value()); |
| 1659 __ movq(rdx, Operand(rsp, 0)); | 1657 __ movq(rdx, Operand(rsp, 0)); |
| 1660 Handle<Code> ic = is_classic_mode() | 1658 CallStoreIC(NOT_CONTEXTUAL, key->LiteralFeedbackId()); |
| 1661 ? isolate()->builtins()->StoreIC_Initialize() | |
| 1662 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 1663 CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId()); | |
| 1664 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1659 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1665 } else { | 1660 } else { |
| 1666 VisitForEffect(value); | 1661 VisitForEffect(value); |
| 1667 } | 1662 } |
| 1668 break; | 1663 break; |
| 1669 } | 1664 } |
| 1670 __ push(Operand(rsp, 0)); // Duplicate receiver. | 1665 __ push(Operand(rsp, 0)); // Duplicate receiver. |
| 1671 VisitForStackValue(key); | 1666 VisitForStackValue(key); |
| 1672 VisitForStackValue(value); | 1667 VisitForStackValue(value); |
| 1673 if (property->emit_store()) { | 1668 if (property->emit_store()) { |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2075 __ bind(&l_call); | 2070 __ bind(&l_call); |
| 2076 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); | 2071 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); |
| 2077 CallIC(ic); | 2072 CallIC(ic); |
| 2078 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2073 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 2079 __ Drop(1); // The key is still on the stack; drop it. | 2074 __ Drop(1); // The key is still on the stack; drop it. |
| 2080 | 2075 |
| 2081 // if (!result.done) goto l_try; | 2076 // if (!result.done) goto l_try; |
| 2082 __ bind(&l_loop); | 2077 __ bind(&l_loop); |
| 2083 __ push(rax); // save result | 2078 __ push(rax); // save result |
| 2084 __ LoadRoot(rcx, Heap::kdone_stringRootIndex); // "done" | 2079 __ LoadRoot(rcx, Heap::kdone_stringRootIndex); // "done" |
| 2085 Handle<Code> done_ic = isolate()->builtins()->LoadIC_Initialize(); | 2080 CallLoadIC(NOT_CONTEXTUAL); // result.done in rax |
| 2086 CallIC(done_ic); // result.done in rax | |
| 2087 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); | 2081 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); |
| 2088 CallIC(bool_ic); | 2082 CallIC(bool_ic); |
| 2089 __ testq(result_register(), result_register()); | 2083 __ testq(result_register(), result_register()); |
| 2090 __ j(zero, &l_try); | 2084 __ j(zero, &l_try); |
| 2091 | 2085 |
| 2092 // result.value | 2086 // result.value |
| 2093 __ pop(rax); // result | 2087 __ pop(rax); // result |
| 2094 __ LoadRoot(rcx, Heap::kvalue_stringRootIndex); // "value" | 2088 __ LoadRoot(rcx, Heap::kvalue_stringRootIndex); // "value" |
| 2095 Handle<Code> value_ic = isolate()->builtins()->LoadIC_Initialize(); | 2089 CallLoadIC(NOT_CONTEXTUAL); // result.value in rax |
| 2096 CallIC(value_ic); // result.value in rax | |
| 2097 context()->DropAndPlug(2, rax); // drop iter and g | 2090 context()->DropAndPlug(2, rax); // drop iter and g |
| 2098 break; | 2091 break; |
| 2099 } | 2092 } |
| 2100 } | 2093 } |
| 2101 } | 2094 } |
| 2102 | 2095 |
| 2103 | 2096 |
| 2104 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 2097 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
| 2105 Expression *value, | 2098 Expression *value, |
| 2106 JSGeneratorObject::ResumeMode resume_mode) { | 2099 JSGeneratorObject::ResumeMode resume_mode) { |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2232 // root set. | 2225 // root set. |
| 2233 __ RecordWriteField(rax, JSGeneratorObject::kResultValuePropertyOffset, | 2226 __ RecordWriteField(rax, JSGeneratorObject::kResultValuePropertyOffset, |
| 2234 rcx, rdx, kDontSaveFPRegs); | 2227 rcx, rdx, kDontSaveFPRegs); |
| 2235 } | 2228 } |
| 2236 | 2229 |
| 2237 | 2230 |
| 2238 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2231 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 2239 SetSourcePosition(prop->position()); | 2232 SetSourcePosition(prop->position()); |
| 2240 Literal* key = prop->key()->AsLiteral(); | 2233 Literal* key = prop->key()->AsLiteral(); |
| 2241 __ Move(rcx, key->value()); | 2234 __ Move(rcx, key->value()); |
| 2242 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 2235 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
| 2243 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); | |
| 2244 } | 2236 } |
| 2245 | 2237 |
| 2246 | 2238 |
| 2247 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2239 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 2248 SetSourcePosition(prop->position()); | 2240 SetSourcePosition(prop->position()); |
| 2249 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2241 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2250 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); | 2242 CallIC(ic, NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
| 2251 } | 2243 } |
| 2252 | 2244 |
| 2253 | 2245 |
| 2254 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2246 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
| 2255 Token::Value op, | 2247 Token::Value op, |
| 2256 OverwriteMode mode, | 2248 OverwriteMode mode, |
| 2257 Expression* left, | 2249 Expression* left, |
| 2258 Expression* right) { | 2250 Expression* right) { |
| 2259 // Do combined smi check of the operands. Left operand is on the | 2251 // Do combined smi check of the operands. Left operand is on the |
| 2260 // stack (popped into rdx). Right operand is in rax but moved into | 2252 // stack (popped into rdx). Right operand is in rax but moved into |
| 2261 // rcx to make the shifts easier. | 2253 // rcx to make the shifts easier. |
| 2262 Label done, stub_call, smi_case; | 2254 Label done, stub_call, smi_case; |
| 2263 __ pop(rdx); | 2255 __ pop(rdx); |
| 2264 __ movq(rcx, rax); | 2256 __ movq(rcx, rax); |
| 2265 __ or_(rax, rdx); | 2257 __ or_(rax, rdx); |
| 2266 JumpPatchSite patch_site(masm_); | 2258 JumpPatchSite patch_site(masm_); |
| 2267 patch_site.EmitJumpIfSmi(rax, &smi_case, Label::kNear); | 2259 patch_site.EmitJumpIfSmi(rax, &smi_case, Label::kNear); |
| 2268 | 2260 |
| 2269 __ bind(&stub_call); | 2261 __ bind(&stub_call); |
| 2270 __ movq(rax, rcx); | 2262 __ movq(rax, rcx); |
| 2271 BinaryOpICStub stub(op, mode); | 2263 BinaryOpICStub stub(op, mode); |
| 2272 CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, | 2264 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, |
| 2273 expr->BinaryOperationFeedbackId()); | 2265 expr->BinaryOperationFeedbackId()); |
| 2274 patch_site.EmitPatchInfo(); | 2266 patch_site.EmitPatchInfo(); |
| 2275 __ jmp(&done, Label::kNear); | 2267 __ jmp(&done, Label::kNear); |
| 2276 | 2268 |
| 2277 __ bind(&smi_case); | 2269 __ bind(&smi_case); |
| 2278 switch (op) { | 2270 switch (op) { |
| 2279 case Token::SAR: | 2271 case Token::SAR: |
| 2280 __ SmiShiftArithmeticRight(rax, rdx, rcx); | 2272 __ SmiShiftArithmeticRight(rax, rdx, rcx); |
| 2281 break; | 2273 break; |
| 2282 case Token::SHL: | 2274 case Token::SHL: |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2312 context()->Plug(rax); | 2304 context()->Plug(rax); |
| 2313 } | 2305 } |
| 2314 | 2306 |
| 2315 | 2307 |
| 2316 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 2308 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
| 2317 Token::Value op, | 2309 Token::Value op, |
| 2318 OverwriteMode mode) { | 2310 OverwriteMode mode) { |
| 2319 __ pop(rdx); | 2311 __ pop(rdx); |
| 2320 BinaryOpICStub stub(op, mode); | 2312 BinaryOpICStub stub(op, mode); |
| 2321 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2313 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
| 2322 CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, | 2314 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, |
| 2323 expr->BinaryOperationFeedbackId()); | 2315 expr->BinaryOperationFeedbackId()); |
| 2324 patch_site.EmitPatchInfo(); | 2316 patch_site.EmitPatchInfo(); |
| 2325 context()->Plug(rax); | 2317 context()->Plug(rax); |
| 2326 } | 2318 } |
| 2327 | 2319 |
| 2328 | 2320 |
| 2329 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2321 void FullCodeGenerator::EmitAssignment(Expression* expr) { |
| 2330 // Invalid left-hand sides are rewritten by the parser to have a 'throw | 2322 // Invalid left-hand sides are rewritten by the parser to have a 'throw |
| 2331 // ReferenceError' on the left-hand side. | 2323 // ReferenceError' on the left-hand side. |
| 2332 if (!expr->IsValidLeftHandSide()) { | 2324 if (!expr->IsValidLeftHandSide()) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2351 EffectContext context(this); | 2343 EffectContext context(this); |
| 2352 EmitVariableAssignment(var, Token::ASSIGN); | 2344 EmitVariableAssignment(var, Token::ASSIGN); |
| 2353 break; | 2345 break; |
| 2354 } | 2346 } |
| 2355 case NAMED_PROPERTY: { | 2347 case NAMED_PROPERTY: { |
| 2356 __ push(rax); // Preserve value. | 2348 __ push(rax); // Preserve value. |
| 2357 VisitForAccumulatorValue(prop->obj()); | 2349 VisitForAccumulatorValue(prop->obj()); |
| 2358 __ movq(rdx, rax); | 2350 __ movq(rdx, rax); |
| 2359 __ pop(rax); // Restore value. | 2351 __ pop(rax); // Restore value. |
| 2360 __ Move(rcx, prop->key()->AsLiteral()->value()); | 2352 __ Move(rcx, prop->key()->AsLiteral()->value()); |
| 2361 Handle<Code> ic = is_classic_mode() | 2353 CallStoreIC(NOT_CONTEXTUAL); |
| 2362 ? isolate()->builtins()->StoreIC_Initialize() | |
| 2363 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 2364 CallIC(ic); | |
| 2365 break; | 2354 break; |
| 2366 } | 2355 } |
| 2367 case KEYED_PROPERTY: { | 2356 case KEYED_PROPERTY: { |
| 2368 __ push(rax); // Preserve value. | 2357 __ push(rax); // Preserve value. |
| 2369 VisitForStackValue(prop->obj()); | 2358 VisitForStackValue(prop->obj()); |
| 2370 VisitForAccumulatorValue(prop->key()); | 2359 VisitForAccumulatorValue(prop->key()); |
| 2371 __ movq(rcx, rax); | 2360 __ movq(rcx, rax); |
| 2372 __ pop(rdx); | 2361 __ pop(rdx); |
| 2373 __ pop(rax); // Restore value. | 2362 __ pop(rax); // Restore value. |
| 2374 Handle<Code> ic = is_classic_mode() | 2363 Handle<Code> ic = is_classic_mode() |
| 2375 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2364 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 2376 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2365 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 2377 CallIC(ic); | 2366 CallIC(ic); |
| 2378 break; | 2367 break; |
| 2379 } | 2368 } |
| 2380 } | 2369 } |
| 2381 context()->Plug(rax); | 2370 context()->Plug(rax); |
| 2382 } | 2371 } |
| 2383 | 2372 |
| 2384 | 2373 |
| 2385 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 2374 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
| 2386 Token::Value op) { | 2375 Token::Value op) { |
| 2387 if (var->IsUnallocated()) { | 2376 if (var->IsUnallocated()) { |
| 2388 // Global var, const, or let. | 2377 // Global var, const, or let. |
| 2389 __ Move(rcx, var->name()); | 2378 __ Move(rcx, var->name()); |
| 2390 __ movq(rdx, GlobalObjectOperand()); | 2379 __ movq(rdx, GlobalObjectOperand()); |
| 2391 Handle<Code> ic = is_classic_mode() | 2380 CallStoreIC(CONTEXTUAL); |
| 2392 ? isolate()->builtins()->StoreIC_Initialize() | |
| 2393 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 2394 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | |
| 2395 } else if (op == Token::INIT_CONST) { | 2381 } else if (op == Token::INIT_CONST) { |
| 2396 // Const initializers need a write barrier. | 2382 // Const initializers need a write barrier. |
| 2397 ASSERT(!var->IsParameter()); // No const parameters. | 2383 ASSERT(!var->IsParameter()); // No const parameters. |
| 2398 if (var->IsStackLocal()) { | 2384 if (var->IsStackLocal()) { |
| 2399 Label skip; | 2385 Label skip; |
| 2400 __ movq(rdx, StackOperand(var)); | 2386 __ movq(rdx, StackOperand(var)); |
| 2401 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); | 2387 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); |
| 2402 __ j(not_equal, &skip); | 2388 __ j(not_equal, &skip); |
| 2403 __ movq(StackOperand(var), rax); | 2389 __ movq(StackOperand(var), rax); |
| 2404 __ bind(&skip); | 2390 __ bind(&skip); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2475 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2461 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
| 2476 // Assignment to a property, using a named store IC. | 2462 // Assignment to a property, using a named store IC. |
| 2477 Property* prop = expr->target()->AsProperty(); | 2463 Property* prop = expr->target()->AsProperty(); |
| 2478 ASSERT(prop != NULL); | 2464 ASSERT(prop != NULL); |
| 2479 ASSERT(prop->key()->AsLiteral() != NULL); | 2465 ASSERT(prop->key()->AsLiteral() != NULL); |
| 2480 | 2466 |
| 2481 // Record source code position before IC call. | 2467 // Record source code position before IC call. |
| 2482 SetSourcePosition(expr->position()); | 2468 SetSourcePosition(expr->position()); |
| 2483 __ Move(rcx, prop->key()->AsLiteral()->value()); | 2469 __ Move(rcx, prop->key()->AsLiteral()->value()); |
| 2484 __ pop(rdx); | 2470 __ pop(rdx); |
| 2485 Handle<Code> ic = is_classic_mode() | 2471 CallStoreIC(NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); |
| 2486 ? isolate()->builtins()->StoreIC_Initialize() | |
| 2487 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 2488 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); | |
| 2489 | 2472 |
| 2490 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2473 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2491 context()->Plug(rax); | 2474 context()->Plug(rax); |
| 2492 } | 2475 } |
| 2493 | 2476 |
| 2494 | 2477 |
| 2495 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2478 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 2496 // Assignment to a property, using a keyed store IC. | 2479 // Assignment to a property, using a keyed store IC. |
| 2497 | 2480 |
| 2498 __ pop(rcx); | 2481 __ pop(rcx); |
| 2499 __ pop(rdx); | 2482 __ pop(rdx); |
| 2500 // Record source code position before IC call. | 2483 // Record source code position before IC call. |
| 2501 SetSourcePosition(expr->position()); | 2484 SetSourcePosition(expr->position()); |
| 2502 Handle<Code> ic = is_classic_mode() | 2485 Handle<Code> ic = is_classic_mode() |
| 2503 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2486 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 2504 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2487 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 2505 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); | 2488 CallIC(ic, NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); |
| 2506 | 2489 |
| 2507 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2490 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2508 context()->Plug(rax); | 2491 context()->Plug(rax); |
| 2509 } | 2492 } |
| 2510 | 2493 |
| 2511 | 2494 |
| 2512 void FullCodeGenerator::VisitProperty(Property* expr) { | 2495 void FullCodeGenerator::VisitProperty(Property* expr) { |
| 2513 Comment cmnt(masm_, "[ Property"); | 2496 Comment cmnt(masm_, "[ Property"); |
| 2514 Expression* key = expr->key(); | 2497 Expression* key = expr->key(); |
| 2515 | 2498 |
| 2516 if (key->IsPropertyName()) { | 2499 if (key->IsPropertyName()) { |
| 2517 VisitForAccumulatorValue(expr->obj()); | 2500 VisitForAccumulatorValue(expr->obj()); |
| 2518 EmitNamedPropertyLoad(expr); | 2501 EmitNamedPropertyLoad(expr); |
| 2519 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2502 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
| 2520 context()->Plug(rax); | 2503 context()->Plug(rax); |
| 2521 } else { | 2504 } else { |
| 2522 VisitForStackValue(expr->obj()); | 2505 VisitForStackValue(expr->obj()); |
| 2523 VisitForAccumulatorValue(expr->key()); | 2506 VisitForAccumulatorValue(expr->key()); |
| 2524 __ pop(rdx); | 2507 __ pop(rdx); |
| 2525 EmitKeyedPropertyLoad(expr); | 2508 EmitKeyedPropertyLoad(expr); |
| 2526 context()->Plug(rax); | 2509 context()->Plug(rax); |
| 2527 } | 2510 } |
| 2528 } | 2511 } |
| 2529 | 2512 |
| 2530 | 2513 |
| 2531 void FullCodeGenerator::CallIC(Handle<Code> code, | 2514 void FullCodeGenerator::CallIC(Handle<Code> code, |
| 2532 RelocInfo::Mode rmode, | 2515 ContextualMode mode, |
| 2533 TypeFeedbackId ast_id) { | 2516 TypeFeedbackId ast_id) { |
| 2534 ic_total_count_++; | 2517 ic_total_count_++; |
| 2535 __ call(code, rmode, ast_id); | 2518 ASSERT(mode != CONTEXTUAL || ast_id.IsNone()); |
| 2519 __ call(code, RelocInfo::CODE_TARGET, ast_id); |
| 2536 } | 2520 } |
| 2537 | 2521 |
| 2538 | 2522 |
| 2539 void FullCodeGenerator::EmitCallWithIC(Call* expr, | 2523 void FullCodeGenerator::EmitCallWithIC(Call* expr, |
| 2540 Handle<Object> name, | 2524 Handle<Object> name, |
| 2541 RelocInfo::Mode mode) { | 2525 ContextualMode mode) { |
| 2542 // Code common for calls using the IC. | 2526 // Code common for calls using the IC. |
| 2543 ZoneList<Expression*>* args = expr->arguments(); | 2527 ZoneList<Expression*>* args = expr->arguments(); |
| 2544 int arg_count = args->length(); | 2528 int arg_count = args->length(); |
| 2545 { PreservePositionScope scope(masm()->positions_recorder()); | 2529 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2546 for (int i = 0; i < arg_count; i++) { | 2530 for (int i = 0; i < arg_count; i++) { |
| 2547 VisitForStackValue(args->at(i)); | 2531 VisitForStackValue(args->at(i)); |
| 2548 } | 2532 } |
| 2549 __ Move(rcx, name); | 2533 __ Move(rcx, name); |
| 2550 } | 2534 } |
| 2551 // Record source position for debugger. | 2535 // Record source position for debugger. |
| 2552 SetSourcePosition(expr->position()); | 2536 SetSourcePosition(expr->position()); |
| 2553 // Call the IC initialization code. | 2537 // Call the IC initialization code. |
| 2554 Handle<Code> ic = | 2538 Handle<Code> ic = |
| 2555 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 2539 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
| 2556 CallIC(ic, mode, expr->CallFeedbackId()); | 2540 TypeFeedbackId ast_id = mode == CONTEXTUAL |
| 2541 ? TypeFeedbackId::None() |
| 2542 : expr->CallFeedbackId(); |
| 2543 CallIC(ic, mode, ast_id); |
| 2557 RecordJSReturnSite(expr); | 2544 RecordJSReturnSite(expr); |
| 2558 // Restore context register. | 2545 // Restore context register. |
| 2559 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2546 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 2560 context()->Plug(rax); | 2547 context()->Plug(rax); |
| 2561 } | 2548 } |
| 2562 | 2549 |
| 2563 | 2550 |
| 2564 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2551 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
| 2565 Expression* key) { | 2552 Expression* key) { |
| 2566 // Load the key. | 2553 // Load the key. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2579 for (int i = 0; i < arg_count; i++) { | 2566 for (int i = 0; i < arg_count; i++) { |
| 2580 VisitForStackValue(args->at(i)); | 2567 VisitForStackValue(args->at(i)); |
| 2581 } | 2568 } |
| 2582 } | 2569 } |
| 2583 // Record source position for debugger. | 2570 // Record source position for debugger. |
| 2584 SetSourcePosition(expr->position()); | 2571 SetSourcePosition(expr->position()); |
| 2585 // Call the IC initialization code. | 2572 // Call the IC initialization code. |
| 2586 Handle<Code> ic = | 2573 Handle<Code> ic = |
| 2587 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); | 2574 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); |
| 2588 __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key. | 2575 __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key. |
| 2589 CallIC(ic, RelocInfo::CODE_TARGET, expr->CallFeedbackId()); | 2576 CallIC(ic, NOT_CONTEXTUAL, expr->CallFeedbackId()); |
| 2590 RecordJSReturnSite(expr); | 2577 RecordJSReturnSite(expr); |
| 2591 // Restore context register. | 2578 // Restore context register. |
| 2592 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2579 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 2593 context()->DropAndPlug(1, rax); // Drop the key still on the stack. | 2580 context()->DropAndPlug(1, rax); // Drop the key still on the stack. |
| 2594 } | 2581 } |
| 2595 | 2582 |
| 2596 | 2583 |
| 2597 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { | 2584 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { |
| 2598 // Code common for calls using the call stub. | 2585 // Code common for calls using the call stub. |
| 2599 ZoneList<Expression*>* args = expr->arguments(); | 2586 ZoneList<Expression*>* args = expr->arguments(); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2691 __ movq(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); | 2678 __ movq(rdi, Operand(rsp, (arg_count + 1) * kPointerSize)); |
| 2692 __ CallStub(&stub); | 2679 __ CallStub(&stub); |
| 2693 RecordJSReturnSite(expr); | 2680 RecordJSReturnSite(expr); |
| 2694 // Restore context register. | 2681 // Restore context register. |
| 2695 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2682 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 2696 context()->DropAndPlug(1, rax); | 2683 context()->DropAndPlug(1, rax); |
| 2697 } else if (proxy != NULL && proxy->var()->IsUnallocated()) { | 2684 } else if (proxy != NULL && proxy->var()->IsUnallocated()) { |
| 2698 // Call to a global variable. Push global object as receiver for the | 2685 // Call to a global variable. Push global object as receiver for the |
| 2699 // call IC lookup. | 2686 // call IC lookup. |
| 2700 __ push(GlobalObjectOperand()); | 2687 __ push(GlobalObjectOperand()); |
| 2701 EmitCallWithIC(expr, proxy->name(), RelocInfo::CODE_TARGET_CONTEXT); | 2688 EmitCallWithIC(expr, proxy->name(), CONTEXTUAL); |
| 2702 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 2689 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
| 2703 // Call to a lookup slot (dynamically introduced variable). | 2690 // Call to a lookup slot (dynamically introduced variable). |
| 2704 Label slow, done; | 2691 Label slow, done; |
| 2705 | 2692 |
| 2706 { PreservePositionScope scope(masm()->positions_recorder()); | 2693 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2707 // Generate code for loading from variables potentially shadowed by | 2694 // Generate code for loading from variables potentially shadowed by |
| 2708 // eval-introduced variables. | 2695 // eval-introduced variables. |
| 2709 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); | 2696 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); |
| 2710 } | 2697 } |
| 2711 __ bind(&slow); | 2698 __ bind(&slow); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2735 // LoadContextSlot. That object could be the hole if the receiver is | 2722 // LoadContextSlot. That object could be the hole if the receiver is |
| 2736 // implicitly the global object. | 2723 // implicitly the global object. |
| 2737 EmitCallWithStub(expr, RECEIVER_MIGHT_BE_IMPLICIT); | 2724 EmitCallWithStub(expr, RECEIVER_MIGHT_BE_IMPLICIT); |
| 2738 } else if (property != NULL) { | 2725 } else if (property != NULL) { |
| 2739 { PreservePositionScope scope(masm()->positions_recorder()); | 2726 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2740 VisitForStackValue(property->obj()); | 2727 VisitForStackValue(property->obj()); |
| 2741 } | 2728 } |
| 2742 if (property->key()->IsPropertyName()) { | 2729 if (property->key()->IsPropertyName()) { |
| 2743 EmitCallWithIC(expr, | 2730 EmitCallWithIC(expr, |
| 2744 property->key()->AsLiteral()->value(), | 2731 property->key()->AsLiteral()->value(), |
| 2745 RelocInfo::CODE_TARGET); | 2732 NOT_CONTEXTUAL); |
| 2746 } else { | 2733 } else { |
| 2747 EmitKeyedCallWithIC(expr, property->key()); | 2734 EmitKeyedCallWithIC(expr, property->key()); |
| 2748 } | 2735 } |
| 2749 } else { | 2736 } else { |
| 2750 // Call to an arbitrary expression not handled specially above. | 2737 // Call to an arbitrary expression not handled specially above. |
| 2751 { PreservePositionScope scope(masm()->positions_recorder()); | 2738 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2752 VisitForStackValue(callee); | 2739 VisitForStackValue(callee); |
| 2753 } | 2740 } |
| 2754 // Load global receiver object. | 2741 // Load global receiver object. |
| 2755 __ movq(rbx, GlobalObjectOperand()); | 2742 __ movq(rbx, GlobalObjectOperand()); |
| (...skipping 1390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4146 | 4133 |
| 4147 // Push the arguments ("left-to-right"). | 4134 // Push the arguments ("left-to-right"). |
| 4148 int arg_count = args->length(); | 4135 int arg_count = args->length(); |
| 4149 for (int i = 0; i < arg_count; i++) { | 4136 for (int i = 0; i < arg_count; i++) { |
| 4150 VisitForStackValue(args->at(i)); | 4137 VisitForStackValue(args->at(i)); |
| 4151 } | 4138 } |
| 4152 | 4139 |
| 4153 if (expr->is_jsruntime()) { | 4140 if (expr->is_jsruntime()) { |
| 4154 // Call the JS runtime function using a call IC. | 4141 // Call the JS runtime function using a call IC. |
| 4155 __ Move(rcx, expr->name()); | 4142 __ Move(rcx, expr->name()); |
| 4156 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; | 4143 ContextualMode mode = NOT_CONTEXTUAL; |
| 4157 Handle<Code> ic = | 4144 Handle<Code> ic = |
| 4158 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 4145 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
| 4159 CallIC(ic, mode, expr->CallRuntimeFeedbackId()); | 4146 CallIC(ic, mode, expr->CallRuntimeFeedbackId()); |
| 4160 // Restore context register. | 4147 // Restore context register. |
| 4161 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 4148 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 4162 } else { | 4149 } else { |
| 4163 __ CallRuntime(expr->function(), arg_count); | 4150 __ CallRuntime(expr->function(), arg_count); |
| 4164 } | 4151 } |
| 4165 context()->Plug(rax); | 4152 context()->Plug(rax); |
| 4166 } | 4153 } |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4400 | 4387 |
| 4401 // Record position before stub call. | 4388 // Record position before stub call. |
| 4402 SetSourcePosition(expr->position()); | 4389 SetSourcePosition(expr->position()); |
| 4403 | 4390 |
| 4404 // Call stub for +1/-1. | 4391 // Call stub for +1/-1. |
| 4405 __ bind(&stub_call); | 4392 __ bind(&stub_call); |
| 4406 __ movq(rdx, rax); | 4393 __ movq(rdx, rax); |
| 4407 __ Move(rax, Smi::FromInt(1)); | 4394 __ Move(rax, Smi::FromInt(1)); |
| 4408 BinaryOpICStub stub(expr->binary_op(), NO_OVERWRITE); | 4395 BinaryOpICStub stub(expr->binary_op(), NO_OVERWRITE); |
| 4409 CallIC(stub.GetCode(isolate()), | 4396 CallIC(stub.GetCode(isolate()), |
| 4410 RelocInfo::CODE_TARGET, | 4397 NOT_CONTEXTUAL, |
| 4411 expr->CountBinOpFeedbackId()); | 4398 expr->CountBinOpFeedbackId()); |
| 4412 patch_site.EmitPatchInfo(); | 4399 patch_site.EmitPatchInfo(); |
| 4413 __ bind(&done); | 4400 __ bind(&done); |
| 4414 | 4401 |
| 4415 // Store the value returned in rax. | 4402 // Store the value returned in rax. |
| 4416 switch (assign_type) { | 4403 switch (assign_type) { |
| 4417 case VARIABLE: | 4404 case VARIABLE: |
| 4418 if (expr->is_postfix()) { | 4405 if (expr->is_postfix()) { |
| 4419 // Perform the assignment as if via '='. | 4406 // Perform the assignment as if via '='. |
| 4420 { EffectContext context(this); | 4407 { EffectContext context(this); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4432 // Perform the assignment as if via '='. | 4419 // Perform the assignment as if via '='. |
| 4433 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4420 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 4434 Token::ASSIGN); | 4421 Token::ASSIGN); |
| 4435 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4422 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4436 context()->Plug(rax); | 4423 context()->Plug(rax); |
| 4437 } | 4424 } |
| 4438 break; | 4425 break; |
| 4439 case NAMED_PROPERTY: { | 4426 case NAMED_PROPERTY: { |
| 4440 __ Move(rcx, prop->key()->AsLiteral()->value()); | 4427 __ Move(rcx, prop->key()->AsLiteral()->value()); |
| 4441 __ pop(rdx); | 4428 __ pop(rdx); |
| 4442 Handle<Code> ic = is_classic_mode() | 4429 CallStoreIC(NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); |
| 4443 ? isolate()->builtins()->StoreIC_Initialize() | |
| 4444 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 4445 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); | |
| 4446 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4430 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4447 if (expr->is_postfix()) { | 4431 if (expr->is_postfix()) { |
| 4448 if (!context()->IsEffect()) { | 4432 if (!context()->IsEffect()) { |
| 4449 context()->PlugTOS(); | 4433 context()->PlugTOS(); |
| 4450 } | 4434 } |
| 4451 } else { | 4435 } else { |
| 4452 context()->Plug(rax); | 4436 context()->Plug(rax); |
| 4453 } | 4437 } |
| 4454 break; | 4438 break; |
| 4455 } | 4439 } |
| 4456 case KEYED_PROPERTY: { | 4440 case KEYED_PROPERTY: { |
| 4457 __ pop(rcx); | 4441 __ pop(rcx); |
| 4458 __ pop(rdx); | 4442 __ pop(rdx); |
| 4459 Handle<Code> ic = is_classic_mode() | 4443 Handle<Code> ic = is_classic_mode() |
| 4460 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 4444 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 4461 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 4445 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 4462 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); | 4446 CallIC(ic, NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); |
| 4463 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4447 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4464 if (expr->is_postfix()) { | 4448 if (expr->is_postfix()) { |
| 4465 if (!context()->IsEffect()) { | 4449 if (!context()->IsEffect()) { |
| 4466 context()->PlugTOS(); | 4450 context()->PlugTOS(); |
| 4467 } | 4451 } |
| 4468 } else { | 4452 } else { |
| 4469 context()->Plug(rax); | 4453 context()->Plug(rax); |
| 4470 } | 4454 } |
| 4471 break; | 4455 break; |
| 4472 } | 4456 } |
| 4473 } | 4457 } |
| 4474 } | 4458 } |
| 4475 | 4459 |
| 4476 | 4460 |
| 4477 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 4461 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
| 4478 VariableProxy* proxy = expr->AsVariableProxy(); | 4462 VariableProxy* proxy = expr->AsVariableProxy(); |
| 4479 ASSERT(!context()->IsEffect()); | 4463 ASSERT(!context()->IsEffect()); |
| 4480 ASSERT(!context()->IsTest()); | 4464 ASSERT(!context()->IsTest()); |
| 4481 | 4465 |
| 4482 if (proxy != NULL && proxy->var()->IsUnallocated()) { | 4466 if (proxy != NULL && proxy->var()->IsUnallocated()) { |
| 4483 Comment cmnt(masm_, "Global variable"); | 4467 Comment cmnt(masm_, "Global variable"); |
| 4484 __ Move(rcx, proxy->name()); | 4468 __ Move(rcx, proxy->name()); |
| 4485 __ movq(rax, GlobalObjectOperand()); | 4469 __ movq(rax, GlobalObjectOperand()); |
| 4486 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | |
| 4487 // Use a regular load, not a contextual load, to avoid a reference | 4470 // Use a regular load, not a contextual load, to avoid a reference |
| 4488 // error. | 4471 // error. |
| 4489 CallIC(ic); | 4472 CallLoadIC(NOT_CONTEXTUAL); |
| 4490 PrepareForBailout(expr, TOS_REG); | 4473 PrepareForBailout(expr, TOS_REG); |
| 4491 context()->Plug(rax); | 4474 context()->Plug(rax); |
| 4492 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 4475 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
| 4493 Label done, slow; | 4476 Label done, slow; |
| 4494 | 4477 |
| 4495 // Generate code for loading from variables potentially shadowed | 4478 // Generate code for loading from variables potentially shadowed |
| 4496 // by eval-introduced variables. | 4479 // by eval-introduced variables. |
| 4497 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); | 4480 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); |
| 4498 | 4481 |
| 4499 __ bind(&slow); | 4482 __ bind(&slow); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4641 __ or_(rcx, rax); | 4624 __ or_(rcx, rax); |
| 4642 patch_site.EmitJumpIfNotSmi(rcx, &slow_case, Label::kNear); | 4625 patch_site.EmitJumpIfNotSmi(rcx, &slow_case, Label::kNear); |
| 4643 __ cmpq(rdx, rax); | 4626 __ cmpq(rdx, rax); |
| 4644 Split(cc, if_true, if_false, NULL); | 4627 Split(cc, if_true, if_false, NULL); |
| 4645 __ bind(&slow_case); | 4628 __ bind(&slow_case); |
| 4646 } | 4629 } |
| 4647 | 4630 |
| 4648 // Record position and call the compare IC. | 4631 // Record position and call the compare IC. |
| 4649 SetSourcePosition(expr->position()); | 4632 SetSourcePosition(expr->position()); |
| 4650 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); | 4633 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); |
| 4651 CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); | 4634 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); |
| 4652 patch_site.EmitPatchInfo(); | 4635 patch_site.EmitPatchInfo(); |
| 4653 | 4636 |
| 4654 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4637 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 4655 __ testq(rax, rax); | 4638 __ testq(rax, rax); |
| 4656 Split(cc, if_true, if_false, fall_through); | 4639 Split(cc, if_true, if_false, fall_through); |
| 4657 } | 4640 } |
| 4658 } | 4641 } |
| 4659 | 4642 |
| 4660 // Convert the result of the comparison into one expected for this | 4643 // Convert the result of the comparison into one expected for this |
| 4661 // expression's context. | 4644 // expression's context. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 4676 VisitForAccumulatorValue(sub_expr); | 4659 VisitForAccumulatorValue(sub_expr); |
| 4677 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4660 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 4678 if (expr->op() == Token::EQ_STRICT) { | 4661 if (expr->op() == Token::EQ_STRICT) { |
| 4679 Heap::RootListIndex nil_value = nil == kNullValue ? | 4662 Heap::RootListIndex nil_value = nil == kNullValue ? |
| 4680 Heap::kNullValueRootIndex : | 4663 Heap::kNullValueRootIndex : |
| 4681 Heap::kUndefinedValueRootIndex; | 4664 Heap::kUndefinedValueRootIndex; |
| 4682 __ CompareRoot(rax, nil_value); | 4665 __ CompareRoot(rax, nil_value); |
| 4683 Split(equal, if_true, if_false, fall_through); | 4666 Split(equal, if_true, if_false, fall_through); |
| 4684 } else { | 4667 } else { |
| 4685 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); | 4668 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); |
| 4686 CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); | 4669 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); |
| 4687 __ testq(rax, rax); | 4670 __ testq(rax, rax); |
| 4688 Split(not_zero, if_true, if_false, fall_through); | 4671 Split(not_zero, if_true, if_false, fall_through); |
| 4689 } | 4672 } |
| 4690 context()->Plug(if_true, if_false); | 4673 context()->Plug(if_true, if_false); |
| 4691 } | 4674 } |
| 4692 | 4675 |
| 4693 | 4676 |
| 4694 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { | 4677 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { |
| 4695 __ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 4678 __ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
| 4696 context()->Plug(rax); | 4679 context()->Plug(rax); |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4906 | 4889 |
| 4907 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4890 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
| 4908 Assembler::target_address_at(call_target_address)); | 4891 Assembler::target_address_at(call_target_address)); |
| 4909 return OSR_AFTER_STACK_CHECK; | 4892 return OSR_AFTER_STACK_CHECK; |
| 4910 } | 4893 } |
| 4911 | 4894 |
| 4912 | 4895 |
| 4913 } } // namespace v8::internal | 4896 } } // namespace v8::internal |
| 4914 | 4897 |
| 4915 #endif // V8_TARGET_ARCH_X64 | 4898 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |