| 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 654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 665 } | 665 } |
| 666 } | 666 } |
| 667 | 667 |
| 668 | 668 |
| 669 void FullCodeGenerator::DoTest(Expression* condition, | 669 void FullCodeGenerator::DoTest(Expression* condition, |
| 670 Label* if_true, | 670 Label* if_true, |
| 671 Label* if_false, | 671 Label* if_false, |
| 672 Label* fall_through) { | 672 Label* fall_through) { |
| 673 __ mov(a0, result_register()); | 673 __ mov(a0, result_register()); |
| 674 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); | 674 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); |
| 675 CallIC(ic, RelocInfo::CODE_TARGET, condition->test_id()); | 675 CallIC(ic, NOT_CONTEXTUAL, condition->test_id()); |
| 676 __ mov(at, zero_reg); | 676 __ mov(at, zero_reg); |
| 677 Split(ne, v0, Operand(at), if_true, if_false, fall_through); | 677 Split(ne, v0, Operand(at), if_true, if_false, fall_through); |
| 678 } | 678 } |
| 679 | 679 |
| 680 | 680 |
| 681 void FullCodeGenerator::Split(Condition cc, | 681 void FullCodeGenerator::Split(Condition cc, |
| 682 Register lhs, | 682 Register lhs, |
| 683 const Operand& rhs, | 683 const Operand& rhs, |
| 684 Label* if_true, | 684 Label* if_true, |
| 685 Label* if_false, | 685 Label* if_false, |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1030 __ Branch(&next_test, ne, a1, Operand(a0)); | 1030 __ Branch(&next_test, ne, a1, Operand(a0)); |
| 1031 __ Drop(1); // Switch value is no longer needed. | 1031 __ Drop(1); // Switch value is no longer needed. |
| 1032 __ Branch(clause->body_target()); | 1032 __ Branch(clause->body_target()); |
| 1033 | 1033 |
| 1034 __ bind(&slow_case); | 1034 __ bind(&slow_case); |
| 1035 } | 1035 } |
| 1036 | 1036 |
| 1037 // Record position before stub call for type feedback. | 1037 // Record position before stub call for type feedback. |
| 1038 SetSourcePosition(clause->position()); | 1038 SetSourcePosition(clause->position()); |
| 1039 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); | 1039 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); |
| 1040 CallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId()); | 1040 CallIC(ic, NOT_CONTEXTUAL, clause->CompareId()); |
| 1041 patch_site.EmitPatchInfo(); | 1041 patch_site.EmitPatchInfo(); |
| 1042 | 1042 |
| 1043 Label skip; | 1043 Label skip; |
| 1044 __ Branch(&skip); | 1044 __ Branch(&skip); |
| 1045 PrepareForBailout(clause, TOS_REG); | 1045 PrepareForBailout(clause, TOS_REG); |
| 1046 __ LoadRoot(at, Heap::kTrueValueRootIndex); | 1046 __ LoadRoot(at, Heap::kTrueValueRootIndex); |
| 1047 __ Branch(&next_test, ne, v0, Operand(at)); | 1047 __ Branch(&next_test, ne, v0, Operand(at)); |
| 1048 __ Drop(1); | 1048 __ Drop(1); |
| 1049 __ Branch(clause->body_target()); | 1049 __ Branch(clause->body_target()); |
| 1050 __ bind(&skip); | 1050 __ bind(&skip); |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1393 __ lw(temp, ContextOperand(next, Context::EXTENSION_INDEX)); | 1393 __ lw(temp, ContextOperand(next, Context::EXTENSION_INDEX)); |
| 1394 __ Branch(slow, ne, temp, Operand(zero_reg)); | 1394 __ Branch(slow, ne, temp, Operand(zero_reg)); |
| 1395 // Load next context in chain. | 1395 // Load next context in chain. |
| 1396 __ lw(next, ContextOperand(next, Context::PREVIOUS_INDEX)); | 1396 __ lw(next, ContextOperand(next, Context::PREVIOUS_INDEX)); |
| 1397 __ Branch(&loop); | 1397 __ Branch(&loop); |
| 1398 __ bind(&fast); | 1398 __ bind(&fast); |
| 1399 } | 1399 } |
| 1400 | 1400 |
| 1401 __ lw(a0, GlobalObjectOperand()); | 1401 __ lw(a0, GlobalObjectOperand()); |
| 1402 __ li(a2, Operand(var->name())); | 1402 __ li(a2, Operand(var->name())); |
| 1403 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 1403 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) |
| 1404 ? RelocInfo::CODE_TARGET | 1404 ? NOT_CONTEXTUAL |
| 1405 : RelocInfo::CODE_TARGET_CONTEXT; | 1405 : CONTEXTUAL; |
| 1406 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1406 CallLoadIC(mode); |
| 1407 CallIC(ic, mode); | |
| 1408 } | 1407 } |
| 1409 | 1408 |
| 1410 | 1409 |
| 1411 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1410 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
| 1412 Label* slow) { | 1411 Label* slow) { |
| 1413 ASSERT(var->IsContextSlot()); | 1412 ASSERT(var->IsContextSlot()); |
| 1414 Register context = cp; | 1413 Register context = cp; |
| 1415 Register next = a3; | 1414 Register next = a3; |
| 1416 Register temp = t0; | 1415 Register temp = t0; |
| 1417 | 1416 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1480 | 1479 |
| 1481 // Three cases: global variables, lookup variables, and all other types of | 1480 // Three cases: global variables, lookup variables, and all other types of |
| 1482 // variables. | 1481 // variables. |
| 1483 switch (var->location()) { | 1482 switch (var->location()) { |
| 1484 case Variable::UNALLOCATED: { | 1483 case Variable::UNALLOCATED: { |
| 1485 Comment cmnt(masm_, "Global variable"); | 1484 Comment cmnt(masm_, "Global variable"); |
| 1486 // Use inline caching. Variable name is passed in a2 and the global | 1485 // Use inline caching. Variable name is passed in a2 and the global |
| 1487 // object (receiver) in a0. | 1486 // object (receiver) in a0. |
| 1488 __ lw(a0, GlobalObjectOperand()); | 1487 __ lw(a0, GlobalObjectOperand()); |
| 1489 __ li(a2, Operand(var->name())); | 1488 __ li(a2, Operand(var->name())); |
| 1490 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1489 CallLoadIC(CONTEXTUAL); |
| 1491 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | |
| 1492 context()->Plug(v0); | 1490 context()->Plug(v0); |
| 1493 break; | 1491 break; |
| 1494 } | 1492 } |
| 1495 | 1493 |
| 1496 case Variable::PARAMETER: | 1494 case Variable::PARAMETER: |
| 1497 case Variable::LOCAL: | 1495 case Variable::LOCAL: |
| 1498 case Variable::CONTEXT: { | 1496 case Variable::CONTEXT: { |
| 1499 Comment cmnt(masm_, var->IsContextSlot() | 1497 Comment cmnt(masm_, var->IsContextSlot() |
| 1500 ? "Context variable" | 1498 ? "Context variable" |
| 1501 : "Stack variable"); | 1499 : "Stack variable"); |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1693 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1691 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1694 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1692 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); |
| 1695 // Fall through. | 1693 // Fall through. |
| 1696 case ObjectLiteral::Property::COMPUTED: | 1694 case ObjectLiteral::Property::COMPUTED: |
| 1697 if (key->value()->IsInternalizedString()) { | 1695 if (key->value()->IsInternalizedString()) { |
| 1698 if (property->emit_store()) { | 1696 if (property->emit_store()) { |
| 1699 VisitForAccumulatorValue(value); | 1697 VisitForAccumulatorValue(value); |
| 1700 __ mov(a0, result_register()); | 1698 __ mov(a0, result_register()); |
| 1701 __ li(a2, Operand(key->value())); | 1699 __ li(a2, Operand(key->value())); |
| 1702 __ lw(a1, MemOperand(sp)); | 1700 __ lw(a1, MemOperand(sp)); |
| 1703 Handle<Code> ic = is_classic_mode() | 1701 CallStoreIC(NOT_CONTEXTUAL, key->LiteralFeedbackId()); |
| 1704 ? isolate()->builtins()->StoreIC_Initialize() | |
| 1705 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 1706 CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId()); | |
| 1707 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1702 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1708 } else { | 1703 } else { |
| 1709 VisitForEffect(value); | 1704 VisitForEffect(value); |
| 1710 } | 1705 } |
| 1711 break; | 1706 break; |
| 1712 } | 1707 } |
| 1713 // Duplicate receiver on stack. | 1708 // Duplicate receiver on stack. |
| 1714 __ lw(a0, MemOperand(sp)); | 1709 __ lw(a0, MemOperand(sp)); |
| 1715 __ push(a0); | 1710 __ push(a0); |
| 1716 VisitForStackValue(key); | 1711 VisitForStackValue(key); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1786 | 1781 |
| 1787 Handle<FixedArray> constant_elements = expr->constant_elements(); | 1782 Handle<FixedArray> constant_elements = expr->constant_elements(); |
| 1788 ASSERT_EQ(2, constant_elements->length()); | 1783 ASSERT_EQ(2, constant_elements->length()); |
| 1789 ElementsKind constant_elements_kind = | 1784 ElementsKind constant_elements_kind = |
| 1790 static_cast<ElementsKind>(Smi::cast(constant_elements->get(0))->value()); | 1785 static_cast<ElementsKind>(Smi::cast(constant_elements->get(0))->value()); |
| 1791 bool has_fast_elements = | 1786 bool has_fast_elements = |
| 1792 IsFastObjectElementsKind(constant_elements_kind); | 1787 IsFastObjectElementsKind(constant_elements_kind); |
| 1793 Handle<FixedArrayBase> constant_elements_values( | 1788 Handle<FixedArrayBase> constant_elements_values( |
| 1794 FixedArrayBase::cast(constant_elements->get(1))); | 1789 FixedArrayBase::cast(constant_elements->get(1))); |
| 1795 | 1790 |
| 1796 AllocationSiteMode allocation_site_mode = FLAG_track_allocation_sites | 1791 AllocationSiteMode allocation_site_mode = TRACK_ALLOCATION_SITE; |
| 1797 ? TRACK_ALLOCATION_SITE : DONT_TRACK_ALLOCATION_SITE; | |
| 1798 if (has_fast_elements && !FLAG_allocation_site_pretenuring) { | 1792 if (has_fast_elements && !FLAG_allocation_site_pretenuring) { |
| 1799 // If the only customer of allocation sites is transitioning, then | 1793 // If the only customer of allocation sites is transitioning, then |
| 1800 // we can turn it off if we don't have anywhere else to transition to. | 1794 // we can turn it off if we don't have anywhere else to transition to. |
| 1801 allocation_site_mode = DONT_TRACK_ALLOCATION_SITE; | 1795 allocation_site_mode = DONT_TRACK_ALLOCATION_SITE; |
| 1802 } | 1796 } |
| 1803 | 1797 |
| 1804 __ mov(a0, result_register()); | 1798 __ mov(a0, result_register()); |
| 1805 __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 1799 __ lw(a3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 1806 __ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset)); | 1800 __ lw(a3, FieldMemOperand(a3, JSFunction::kLiteralsOffset)); |
| 1807 __ li(a2, Operand(Smi::FromInt(expr->literal_index()))); | 1801 __ li(a2, Operand(Smi::FromInt(expr->literal_index()))); |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2111 __ bind(&l_call); | 2105 __ bind(&l_call); |
| 2112 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); | 2106 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); |
| 2113 CallIC(ic); | 2107 CallIC(ic); |
| 2114 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2108 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2115 | 2109 |
| 2116 // if (!result.done) goto l_try; | 2110 // if (!result.done) goto l_try; |
| 2117 __ bind(&l_loop); | 2111 __ bind(&l_loop); |
| 2118 __ mov(a0, v0); | 2112 __ mov(a0, v0); |
| 2119 __ push(a0); // save result | 2113 __ push(a0); // save result |
| 2120 __ LoadRoot(a2, Heap::kdone_stringRootIndex); // "done" | 2114 __ LoadRoot(a2, Heap::kdone_stringRootIndex); // "done" |
| 2121 Handle<Code> done_ic = isolate()->builtins()->LoadIC_Initialize(); | 2115 CallLoadIC(NOT_CONTEXTUAL); // result.done in v0 |
| 2122 CallIC(done_ic); // result.done in v0 | |
| 2123 __ mov(a0, v0); | 2116 __ mov(a0, v0); |
| 2124 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); | 2117 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); |
| 2125 CallIC(bool_ic); | 2118 CallIC(bool_ic); |
| 2126 __ Branch(&l_try, eq, v0, Operand(zero_reg)); | 2119 __ Branch(&l_try, eq, v0, Operand(zero_reg)); |
| 2127 | 2120 |
| 2128 // result.value | 2121 // result.value |
| 2129 __ pop(a0); // result | 2122 __ pop(a0); // result |
| 2130 __ LoadRoot(a2, Heap::kvalue_stringRootIndex); // "value" | 2123 __ LoadRoot(a2, Heap::kvalue_stringRootIndex); // "value" |
| 2131 Handle<Code> value_ic = isolate()->builtins()->LoadIC_Initialize(); | 2124 CallLoadIC(NOT_CONTEXTUAL); // result.value in v0 |
| 2132 CallIC(value_ic); // result.value in v0 | |
| 2133 context()->DropAndPlug(2, v0); // drop iter and g | 2125 context()->DropAndPlug(2, v0); // drop iter and g |
| 2134 break; | 2126 break; |
| 2135 } | 2127 } |
| 2136 } | 2128 } |
| 2137 } | 2129 } |
| 2138 | 2130 |
| 2139 | 2131 |
| 2140 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 2132 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
| 2141 Expression *value, | 2133 Expression *value, |
| 2142 JSGeneratorObject::ResumeMode resume_mode) { | 2134 JSGeneratorObject::ResumeMode resume_mode) { |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2270 a2, a3, kRAHasBeenSaved, kDontSaveFPRegs); | 2262 a2, a3, kRAHasBeenSaved, kDontSaveFPRegs); |
| 2271 } | 2263 } |
| 2272 | 2264 |
| 2273 | 2265 |
| 2274 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2266 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 2275 SetSourcePosition(prop->position()); | 2267 SetSourcePosition(prop->position()); |
| 2276 Literal* key = prop->key()->AsLiteral(); | 2268 Literal* key = prop->key()->AsLiteral(); |
| 2277 __ mov(a0, result_register()); | 2269 __ mov(a0, result_register()); |
| 2278 __ li(a2, Operand(key->value())); | 2270 __ li(a2, Operand(key->value())); |
| 2279 // Call load IC. It has arguments receiver and property name a0 and a2. | 2271 // Call load IC. It has arguments receiver and property name a0 and a2. |
| 2280 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 2272 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
| 2281 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); | |
| 2282 } | 2273 } |
| 2283 | 2274 |
| 2284 | 2275 |
| 2285 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2276 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 2286 SetSourcePosition(prop->position()); | 2277 SetSourcePosition(prop->position()); |
| 2287 __ mov(a0, result_register()); | 2278 __ mov(a0, result_register()); |
| 2288 // Call keyed load IC. It has arguments key and receiver in a0 and a1. | 2279 // Call keyed load IC. It has arguments key and receiver in a0 and a1. |
| 2289 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2280 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2290 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); | 2281 CallIC(ic, NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
| 2291 } | 2282 } |
| 2292 | 2283 |
| 2293 | 2284 |
| 2294 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2285 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
| 2295 Token::Value op, | 2286 Token::Value op, |
| 2296 OverwriteMode mode, | 2287 OverwriteMode mode, |
| 2297 Expression* left_expr, | 2288 Expression* left_expr, |
| 2298 Expression* right_expr) { | 2289 Expression* right_expr) { |
| 2299 Label done, smi_case, stub_call; | 2290 Label done, smi_case, stub_call; |
| 2300 | 2291 |
| 2301 Register scratch1 = a2; | 2292 Register scratch1 = a2; |
| 2302 Register scratch2 = a3; | 2293 Register scratch2 = a3; |
| 2303 | 2294 |
| 2304 // Get the arguments. | 2295 // Get the arguments. |
| 2305 Register left = a1; | 2296 Register left = a1; |
| 2306 Register right = a0; | 2297 Register right = a0; |
| 2307 __ pop(left); | 2298 __ pop(left); |
| 2308 __ mov(a0, result_register()); | 2299 __ mov(a0, result_register()); |
| 2309 | 2300 |
| 2310 // Perform combined smi check on both operands. | 2301 // Perform combined smi check on both operands. |
| 2311 __ Or(scratch1, left, Operand(right)); | 2302 __ Or(scratch1, left, Operand(right)); |
| 2312 STATIC_ASSERT(kSmiTag == 0); | 2303 STATIC_ASSERT(kSmiTag == 0); |
| 2313 JumpPatchSite patch_site(masm_); | 2304 JumpPatchSite patch_site(masm_); |
| 2314 patch_site.EmitJumpIfSmi(scratch1, &smi_case); | 2305 patch_site.EmitJumpIfSmi(scratch1, &smi_case); |
| 2315 | 2306 |
| 2316 __ bind(&stub_call); | 2307 __ bind(&stub_call); |
| 2317 BinaryOpICStub stub(op, mode); | 2308 BinaryOpICStub stub(op, mode); |
| 2318 CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, | 2309 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, |
| 2319 expr->BinaryOperationFeedbackId()); | 2310 expr->BinaryOperationFeedbackId()); |
| 2320 patch_site.EmitPatchInfo(); | 2311 patch_site.EmitPatchInfo(); |
| 2321 __ jmp(&done); | 2312 __ jmp(&done); |
| 2322 | 2313 |
| 2323 __ bind(&smi_case); | 2314 __ bind(&smi_case); |
| 2324 // Smi case. This code works the same way as the smi-smi case in the type | 2315 // Smi case. This code works the same way as the smi-smi case in the type |
| 2325 // recording binary operation stub, see | 2316 // recording binary operation stub, see |
| 2326 switch (op) { | 2317 switch (op) { |
| 2327 case Token::SAR: | 2318 case Token::SAR: |
| 2328 __ Branch(&stub_call); | 2319 __ Branch(&stub_call); |
| 2329 __ GetLeastBitsFromSmi(scratch1, right, 5); | 2320 __ GetLeastBitsFromSmi(scratch1, right, 5); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2391 } | 2382 } |
| 2392 | 2383 |
| 2393 | 2384 |
| 2394 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 2385 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
| 2395 Token::Value op, | 2386 Token::Value op, |
| 2396 OverwriteMode mode) { | 2387 OverwriteMode mode) { |
| 2397 __ mov(a0, result_register()); | 2388 __ mov(a0, result_register()); |
| 2398 __ pop(a1); | 2389 __ pop(a1); |
| 2399 BinaryOpICStub stub(op, mode); | 2390 BinaryOpICStub stub(op, mode); |
| 2400 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2391 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
| 2401 CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, | 2392 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, |
| 2402 expr->BinaryOperationFeedbackId()); | 2393 expr->BinaryOperationFeedbackId()); |
| 2403 patch_site.EmitPatchInfo(); | 2394 patch_site.EmitPatchInfo(); |
| 2404 context()->Plug(v0); | 2395 context()->Plug(v0); |
| 2405 } | 2396 } |
| 2406 | 2397 |
| 2407 | 2398 |
| 2408 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2399 void FullCodeGenerator::EmitAssignment(Expression* expr) { |
| 2409 // Invalid left-hand sides are rewritten by the parser to have a 'throw | 2400 // Invalid left-hand sides are rewritten by the parser to have a 'throw |
| 2410 // ReferenceError' on the left-hand side. | 2401 // ReferenceError' on the left-hand side. |
| 2411 if (!expr->IsValidLeftHandSide()) { | 2402 if (!expr->IsValidLeftHandSide()) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2430 EffectContext context(this); | 2421 EffectContext context(this); |
| 2431 EmitVariableAssignment(var, Token::ASSIGN); | 2422 EmitVariableAssignment(var, Token::ASSIGN); |
| 2432 break; | 2423 break; |
| 2433 } | 2424 } |
| 2434 case NAMED_PROPERTY: { | 2425 case NAMED_PROPERTY: { |
| 2435 __ push(result_register()); // Preserve value. | 2426 __ push(result_register()); // Preserve value. |
| 2436 VisitForAccumulatorValue(prop->obj()); | 2427 VisitForAccumulatorValue(prop->obj()); |
| 2437 __ mov(a1, result_register()); | 2428 __ mov(a1, result_register()); |
| 2438 __ pop(a0); // Restore value. | 2429 __ pop(a0); // Restore value. |
| 2439 __ li(a2, Operand(prop->key()->AsLiteral()->value())); | 2430 __ li(a2, Operand(prop->key()->AsLiteral()->value())); |
| 2440 Handle<Code> ic = is_classic_mode() | 2431 CallStoreIC(NOT_CONTEXTUAL); |
| 2441 ? isolate()->builtins()->StoreIC_Initialize() | |
| 2442 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 2443 CallIC(ic); | |
| 2444 break; | 2432 break; |
| 2445 } | 2433 } |
| 2446 case KEYED_PROPERTY: { | 2434 case KEYED_PROPERTY: { |
| 2447 __ push(result_register()); // Preserve value. | 2435 __ push(result_register()); // Preserve value. |
| 2448 VisitForStackValue(prop->obj()); | 2436 VisitForStackValue(prop->obj()); |
| 2449 VisitForAccumulatorValue(prop->key()); | 2437 VisitForAccumulatorValue(prop->key()); |
| 2450 __ mov(a1, result_register()); | 2438 __ mov(a1, result_register()); |
| 2451 __ Pop(a0, a2); // a0 = restored value. | 2439 __ Pop(a0, a2); // a0 = restored value. |
| 2452 Handle<Code> ic = is_classic_mode() | 2440 Handle<Code> ic = is_classic_mode() |
| 2453 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2441 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 2454 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2442 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 2455 CallIC(ic); | 2443 CallIC(ic); |
| 2456 break; | 2444 break; |
| 2457 } | 2445 } |
| 2458 } | 2446 } |
| 2459 context()->Plug(v0); | 2447 context()->Plug(v0); |
| 2460 } | 2448 } |
| 2461 | 2449 |
| 2462 | 2450 |
| 2463 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 2451 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
| 2464 Token::Value op) { | 2452 Token::Value op) { |
| 2465 if (var->IsUnallocated()) { | 2453 if (var->IsUnallocated()) { |
| 2466 // Global var, const, or let. | 2454 // Global var, const, or let. |
| 2467 __ mov(a0, result_register()); | 2455 __ mov(a0, result_register()); |
| 2468 __ li(a2, Operand(var->name())); | 2456 __ li(a2, Operand(var->name())); |
| 2469 __ lw(a1, GlobalObjectOperand()); | 2457 __ lw(a1, GlobalObjectOperand()); |
| 2470 Handle<Code> ic = is_classic_mode() | 2458 CallStoreIC(CONTEXTUAL); |
| 2471 ? isolate()->builtins()->StoreIC_Initialize() | |
| 2472 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 2473 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | |
| 2474 | |
| 2475 } else if (op == Token::INIT_CONST) { | 2459 } else if (op == Token::INIT_CONST) { |
| 2476 // Const initializers need a write barrier. | 2460 // Const initializers need a write barrier. |
| 2477 ASSERT(!var->IsParameter()); // No const parameters. | 2461 ASSERT(!var->IsParameter()); // No const parameters. |
| 2478 if (var->IsStackLocal()) { | 2462 if (var->IsStackLocal()) { |
| 2479 Label skip; | 2463 Label skip; |
| 2480 __ lw(a1, StackOperand(var)); | 2464 __ lw(a1, StackOperand(var)); |
| 2481 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); | 2465 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); |
| 2482 __ Branch(&skip, ne, a1, Operand(t0)); | 2466 __ Branch(&skip, ne, a1, Operand(t0)); |
| 2483 __ sw(result_register(), StackOperand(var)); | 2467 __ sw(result_register(), StackOperand(var)); |
| 2484 __ bind(&skip); | 2468 __ bind(&skip); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2562 Property* prop = expr->target()->AsProperty(); | 2546 Property* prop = expr->target()->AsProperty(); |
| 2563 ASSERT(prop != NULL); | 2547 ASSERT(prop != NULL); |
| 2564 ASSERT(prop->key()->AsLiteral() != NULL); | 2548 ASSERT(prop->key()->AsLiteral() != NULL); |
| 2565 | 2549 |
| 2566 // Record source code position before IC call. | 2550 // Record source code position before IC call. |
| 2567 SetSourcePosition(expr->position()); | 2551 SetSourcePosition(expr->position()); |
| 2568 __ mov(a0, result_register()); // Load the value. | 2552 __ mov(a0, result_register()); // Load the value. |
| 2569 __ li(a2, Operand(prop->key()->AsLiteral()->value())); | 2553 __ li(a2, Operand(prop->key()->AsLiteral()->value())); |
| 2570 __ pop(a1); | 2554 __ pop(a1); |
| 2571 | 2555 |
| 2572 Handle<Code> ic = is_classic_mode() | 2556 CallStoreIC(NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); |
| 2573 ? isolate()->builtins()->StoreIC_Initialize() | |
| 2574 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 2575 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); | |
| 2576 | 2557 |
| 2577 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2558 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2578 context()->Plug(v0); | 2559 context()->Plug(v0); |
| 2579 } | 2560 } |
| 2580 | 2561 |
| 2581 | 2562 |
| 2582 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2563 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 2583 // Assignment to a property, using a keyed store IC. | 2564 // Assignment to a property, using a keyed store IC. |
| 2584 | 2565 |
| 2585 // Record source code position before IC call. | 2566 // Record source code position before IC call. |
| 2586 SetSourcePosition(expr->position()); | 2567 SetSourcePosition(expr->position()); |
| 2587 // Call keyed store IC. | 2568 // Call keyed store IC. |
| 2588 // The arguments are: | 2569 // The arguments are: |
| 2589 // - a0 is the value, | 2570 // - a0 is the value, |
| 2590 // - a1 is the key, | 2571 // - a1 is the key, |
| 2591 // - a2 is the receiver. | 2572 // - a2 is the receiver. |
| 2592 __ mov(a0, result_register()); | 2573 __ mov(a0, result_register()); |
| 2593 __ Pop(a2, a1); // a1 = key. | 2574 __ Pop(a2, a1); // a1 = key. |
| 2594 | 2575 |
| 2595 Handle<Code> ic = is_classic_mode() | 2576 Handle<Code> ic = is_classic_mode() |
| 2596 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2577 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 2597 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2578 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 2598 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); | 2579 CallIC(ic, NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); |
| 2599 | 2580 |
| 2600 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2581 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2601 context()->Plug(v0); | 2582 context()->Plug(v0); |
| 2602 } | 2583 } |
| 2603 | 2584 |
| 2604 | 2585 |
| 2605 void FullCodeGenerator::VisitProperty(Property* expr) { | 2586 void FullCodeGenerator::VisitProperty(Property* expr) { |
| 2606 Comment cmnt(masm_, "[ Property"); | 2587 Comment cmnt(masm_, "[ Property"); |
| 2607 Expression* key = expr->key(); | 2588 Expression* key = expr->key(); |
| 2608 | 2589 |
| 2609 if (key->IsPropertyName()) { | 2590 if (key->IsPropertyName()) { |
| 2610 VisitForAccumulatorValue(expr->obj()); | 2591 VisitForAccumulatorValue(expr->obj()); |
| 2611 EmitNamedPropertyLoad(expr); | 2592 EmitNamedPropertyLoad(expr); |
| 2612 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2593 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
| 2613 context()->Plug(v0); | 2594 context()->Plug(v0); |
| 2614 } else { | 2595 } else { |
| 2615 VisitForStackValue(expr->obj()); | 2596 VisitForStackValue(expr->obj()); |
| 2616 VisitForAccumulatorValue(expr->key()); | 2597 VisitForAccumulatorValue(expr->key()); |
| 2617 __ pop(a1); | 2598 __ pop(a1); |
| 2618 EmitKeyedPropertyLoad(expr); | 2599 EmitKeyedPropertyLoad(expr); |
| 2619 context()->Plug(v0); | 2600 context()->Plug(v0); |
| 2620 } | 2601 } |
| 2621 } | 2602 } |
| 2622 | 2603 |
| 2623 | 2604 |
| 2624 void FullCodeGenerator::CallIC(Handle<Code> code, | 2605 void FullCodeGenerator::CallIC(Handle<Code> code, |
| 2625 RelocInfo::Mode rmode, | 2606 ContextualMode mode, |
| 2626 TypeFeedbackId id) { | 2607 TypeFeedbackId id) { |
| 2627 ic_total_count_++; | 2608 ic_total_count_++; |
| 2628 __ Call(code, rmode, id); | 2609 ASSERT(mode != CONTEXTUAL || id.IsNone()); |
| 2610 __ Call(code, RelocInfo::CODE_TARGET, id); |
| 2629 } | 2611 } |
| 2630 | 2612 |
| 2631 | 2613 |
| 2632 void FullCodeGenerator::EmitCallWithIC(Call* expr, | 2614 void FullCodeGenerator::EmitCallWithIC(Call* expr, |
| 2633 Handle<Object> name, | 2615 Handle<Object> name, |
| 2634 RelocInfo::Mode mode) { | 2616 ContextualMode mode) { |
| 2635 // Code common for calls using the IC. | 2617 // Code common for calls using the IC. |
| 2636 ZoneList<Expression*>* args = expr->arguments(); | 2618 ZoneList<Expression*>* args = expr->arguments(); |
| 2637 int arg_count = args->length(); | 2619 int arg_count = args->length(); |
| 2638 { PreservePositionScope scope(masm()->positions_recorder()); | 2620 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2639 for (int i = 0; i < arg_count; i++) { | 2621 for (int i = 0; i < arg_count; i++) { |
| 2640 VisitForStackValue(args->at(i)); | 2622 VisitForStackValue(args->at(i)); |
| 2641 } | 2623 } |
| 2642 __ li(a2, Operand(name)); | 2624 __ li(a2, Operand(name)); |
| 2643 } | 2625 } |
| 2644 // Record source position for debugger. | 2626 // Record source position for debugger. |
| 2645 SetSourcePosition(expr->position()); | 2627 SetSourcePosition(expr->position()); |
| 2646 // Call the IC initialization code. | 2628 // Call the IC initialization code. |
| 2647 Handle<Code> ic = | 2629 Handle<Code> ic = |
| 2648 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 2630 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
| 2649 CallIC(ic, mode, expr->CallFeedbackId()); | 2631 TypeFeedbackId ast_id = mode == CONTEXTUAL |
| 2632 ? TypeFeedbackId::None() |
| 2633 : expr->CallFeedbackId(); |
| 2634 CallIC(ic, mode, ast_id); |
| 2650 RecordJSReturnSite(expr); | 2635 RecordJSReturnSite(expr); |
| 2651 // Restore context register. | 2636 // Restore context register. |
| 2652 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2637 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2653 context()->Plug(v0); | 2638 context()->Plug(v0); |
| 2654 } | 2639 } |
| 2655 | 2640 |
| 2656 | 2641 |
| 2657 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2642 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
| 2658 Expression* key) { | 2643 Expression* key) { |
| 2659 // Load the key. | 2644 // Load the key. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2672 for (int i = 0; i < arg_count; i++) { | 2657 for (int i = 0; i < arg_count; i++) { |
| 2673 VisitForStackValue(args->at(i)); | 2658 VisitForStackValue(args->at(i)); |
| 2674 } | 2659 } |
| 2675 } | 2660 } |
| 2676 // Record source position for debugger. | 2661 // Record source position for debugger. |
| 2677 SetSourcePosition(expr->position()); | 2662 SetSourcePosition(expr->position()); |
| 2678 // Call the IC initialization code. | 2663 // Call the IC initialization code. |
| 2679 Handle<Code> ic = | 2664 Handle<Code> ic = |
| 2680 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); | 2665 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); |
| 2681 __ lw(a2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. | 2666 __ lw(a2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. |
| 2682 CallIC(ic, RelocInfo::CODE_TARGET, expr->CallFeedbackId()); | 2667 CallIC(ic, NOT_CONTEXTUAL, expr->CallFeedbackId()); |
| 2683 RecordJSReturnSite(expr); | 2668 RecordJSReturnSite(expr); |
| 2684 // Restore context register. | 2669 // Restore context register. |
| 2685 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2670 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2686 context()->DropAndPlug(1, v0); // Drop the key still on the stack. | 2671 context()->DropAndPlug(1, v0); // Drop the key still on the stack. |
| 2687 } | 2672 } |
| 2688 | 2673 |
| 2689 | 2674 |
| 2690 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { | 2675 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { |
| 2691 // Code common for calls using the call stub. | 2676 // Code common for calls using the call stub. |
| 2692 ZoneList<Expression*>* args = expr->arguments(); | 2677 ZoneList<Expression*>* args = expr->arguments(); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2788 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2773 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 2789 __ CallStub(&stub); | 2774 __ CallStub(&stub); |
| 2790 RecordJSReturnSite(expr); | 2775 RecordJSReturnSite(expr); |
| 2791 // Restore context register. | 2776 // Restore context register. |
| 2792 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2777 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2793 context()->DropAndPlug(1, v0); | 2778 context()->DropAndPlug(1, v0); |
| 2794 } else if (proxy != NULL && proxy->var()->IsUnallocated()) { | 2779 } else if (proxy != NULL && proxy->var()->IsUnallocated()) { |
| 2795 // Push global object as receiver for the call IC. | 2780 // Push global object as receiver for the call IC. |
| 2796 __ lw(a0, GlobalObjectOperand()); | 2781 __ lw(a0, GlobalObjectOperand()); |
| 2797 __ push(a0); | 2782 __ push(a0); |
| 2798 EmitCallWithIC(expr, proxy->name(), RelocInfo::CODE_TARGET_CONTEXT); | 2783 EmitCallWithIC(expr, proxy->name(), CONTEXTUAL); |
| 2799 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 2784 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
| 2800 // Call to a lookup slot (dynamically introduced variable). | 2785 // Call to a lookup slot (dynamically introduced variable). |
| 2801 Label slow, done; | 2786 Label slow, done; |
| 2802 | 2787 |
| 2803 { PreservePositionScope scope(masm()->positions_recorder()); | 2788 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2804 // Generate code for loading from variables potentially shadowed | 2789 // Generate code for loading from variables potentially shadowed |
| 2805 // by eval-introduced variables. | 2790 // by eval-introduced variables. |
| 2806 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); | 2791 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); |
| 2807 } | 2792 } |
| 2808 | 2793 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2835 // by LoadContextSlot. That object could be the hole if the | 2820 // by LoadContextSlot. That object could be the hole if the |
| 2836 // receiver is implicitly the global object. | 2821 // receiver is implicitly the global object. |
| 2837 EmitCallWithStub(expr, RECEIVER_MIGHT_BE_IMPLICIT); | 2822 EmitCallWithStub(expr, RECEIVER_MIGHT_BE_IMPLICIT); |
| 2838 } else if (property != NULL) { | 2823 } else if (property != NULL) { |
| 2839 { PreservePositionScope scope(masm()->positions_recorder()); | 2824 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2840 VisitForStackValue(property->obj()); | 2825 VisitForStackValue(property->obj()); |
| 2841 } | 2826 } |
| 2842 if (property->key()->IsPropertyName()) { | 2827 if (property->key()->IsPropertyName()) { |
| 2843 EmitCallWithIC(expr, | 2828 EmitCallWithIC(expr, |
| 2844 property->key()->AsLiteral()->value(), | 2829 property->key()->AsLiteral()->value(), |
| 2845 RelocInfo::CODE_TARGET); | 2830 NOT_CONTEXTUAL); |
| 2846 } else { | 2831 } else { |
| 2847 EmitKeyedCallWithIC(expr, property->key()); | 2832 EmitKeyedCallWithIC(expr, property->key()); |
| 2848 } | 2833 } |
| 2849 } else { | 2834 } else { |
| 2850 // Call to an arbitrary expression not handled specially above. | 2835 // Call to an arbitrary expression not handled specially above. |
| 2851 { PreservePositionScope scope(masm()->positions_recorder()); | 2836 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2852 VisitForStackValue(callee); | 2837 VisitForStackValue(callee); |
| 2853 } | 2838 } |
| 2854 // Load global receiver object. | 2839 // Push the hole as receiver. |
| 2855 __ lw(a1, GlobalObjectOperand()); | 2840 // It will be correctly replaced in the call stub. |
| 2856 __ lw(a1, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset)); | 2841 __ LoadRoot(a1, Heap::kTheHoleValueRootIndex); |
| 2857 __ push(a1); | 2842 __ push(a1); |
| 2858 // Emit function call. | 2843 // Emit function call. |
| 2859 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); | 2844 EmitCallWithStub(expr, RECEIVER_IS_IMPLICIT); |
| 2860 } | 2845 } |
| 2861 | 2846 |
| 2862 #ifdef DEBUG | 2847 #ifdef DEBUG |
| 2863 // RecordJSReturnSite should have been called. | 2848 // RecordJSReturnSite should have been called. |
| 2864 ASSERT(expr->return_is_recorded_); | 2849 ASSERT(expr->return_is_recorded_); |
| 2865 #endif | 2850 #endif |
| 2866 } | 2851 } |
| 2867 | 2852 |
| 2868 | 2853 |
| 2869 void FullCodeGenerator::VisitCallNew(CallNew* expr) { | 2854 void FullCodeGenerator::VisitCallNew(CallNew* expr) { |
| (...skipping 1336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4206 | 4191 |
| 4207 // Push the arguments ("left-to-right"). | 4192 // Push the arguments ("left-to-right"). |
| 4208 int arg_count = args->length(); | 4193 int arg_count = args->length(); |
| 4209 for (int i = 0; i < arg_count; i++) { | 4194 for (int i = 0; i < arg_count; i++) { |
| 4210 VisitForStackValue(args->at(i)); | 4195 VisitForStackValue(args->at(i)); |
| 4211 } | 4196 } |
| 4212 | 4197 |
| 4213 if (expr->is_jsruntime()) { | 4198 if (expr->is_jsruntime()) { |
| 4214 // Call the JS runtime function. | 4199 // Call the JS runtime function. |
| 4215 __ li(a2, Operand(expr->name())); | 4200 __ li(a2, Operand(expr->name())); |
| 4216 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; | 4201 ContextualMode mode = NOT_CONTEXTUAL; |
| 4217 Handle<Code> ic = | 4202 Handle<Code> ic = |
| 4218 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 4203 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
| 4219 CallIC(ic, mode, expr->CallRuntimeFeedbackId()); | 4204 CallIC(ic, mode, expr->CallRuntimeFeedbackId()); |
| 4220 // Restore context register. | 4205 // Restore context register. |
| 4221 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4206 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 4222 } else { | 4207 } else { |
| 4223 // Call the C runtime function. | 4208 // Call the C runtime function. |
| 4224 __ CallRuntime(expr->function(), arg_count); | 4209 __ CallRuntime(expr->function(), arg_count); |
| 4225 } | 4210 } |
| 4226 context()->Plug(v0); | 4211 context()->Plug(v0); |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4460 | 4445 |
| 4461 __ bind(&stub_call); | 4446 __ bind(&stub_call); |
| 4462 __ mov(a1, v0); | 4447 __ mov(a1, v0); |
| 4463 __ li(a0, Operand(Smi::FromInt(count_value))); | 4448 __ li(a0, Operand(Smi::FromInt(count_value))); |
| 4464 | 4449 |
| 4465 // Record position before stub call. | 4450 // Record position before stub call. |
| 4466 SetSourcePosition(expr->position()); | 4451 SetSourcePosition(expr->position()); |
| 4467 | 4452 |
| 4468 BinaryOpICStub stub(Token::ADD, NO_OVERWRITE); | 4453 BinaryOpICStub stub(Token::ADD, NO_OVERWRITE); |
| 4469 CallIC(stub.GetCode(isolate()), | 4454 CallIC(stub.GetCode(isolate()), |
| 4470 RelocInfo::CODE_TARGET, | 4455 NOT_CONTEXTUAL, |
| 4471 expr->CountBinOpFeedbackId()); | 4456 expr->CountBinOpFeedbackId()); |
| 4472 patch_site.EmitPatchInfo(); | 4457 patch_site.EmitPatchInfo(); |
| 4473 __ bind(&done); | 4458 __ bind(&done); |
| 4474 | 4459 |
| 4475 // Store the value returned in v0. | 4460 // Store the value returned in v0. |
| 4476 switch (assign_type) { | 4461 switch (assign_type) { |
| 4477 case VARIABLE: | 4462 case VARIABLE: |
| 4478 if (expr->is_postfix()) { | 4463 if (expr->is_postfix()) { |
| 4479 { EffectContext context(this); | 4464 { EffectContext context(this); |
| 4480 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4465 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| (...skipping 10 matching lines...) Expand all Loading... |
| 4491 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4476 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 4492 Token::ASSIGN); | 4477 Token::ASSIGN); |
| 4493 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4478 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4494 context()->Plug(v0); | 4479 context()->Plug(v0); |
| 4495 } | 4480 } |
| 4496 break; | 4481 break; |
| 4497 case NAMED_PROPERTY: { | 4482 case NAMED_PROPERTY: { |
| 4498 __ mov(a0, result_register()); // Value. | 4483 __ mov(a0, result_register()); // Value. |
| 4499 __ li(a2, Operand(prop->key()->AsLiteral()->value())); // Name. | 4484 __ li(a2, Operand(prop->key()->AsLiteral()->value())); // Name. |
| 4500 __ pop(a1); // Receiver. | 4485 __ pop(a1); // Receiver. |
| 4501 Handle<Code> ic = is_classic_mode() | 4486 CallStoreIC(NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); |
| 4502 ? isolate()->builtins()->StoreIC_Initialize() | |
| 4503 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
| 4504 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); | |
| 4505 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4487 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4506 if (expr->is_postfix()) { | 4488 if (expr->is_postfix()) { |
| 4507 if (!context()->IsEffect()) { | 4489 if (!context()->IsEffect()) { |
| 4508 context()->PlugTOS(); | 4490 context()->PlugTOS(); |
| 4509 } | 4491 } |
| 4510 } else { | 4492 } else { |
| 4511 context()->Plug(v0); | 4493 context()->Plug(v0); |
| 4512 } | 4494 } |
| 4513 break; | 4495 break; |
| 4514 } | 4496 } |
| 4515 case KEYED_PROPERTY: { | 4497 case KEYED_PROPERTY: { |
| 4516 __ mov(a0, result_register()); // Value. | 4498 __ mov(a0, result_register()); // Value. |
| 4517 __ Pop(a2, a1); // a1 = key, a2 = receiver. | 4499 __ Pop(a2, a1); // a1 = key, a2 = receiver. |
| 4518 Handle<Code> ic = is_classic_mode() | 4500 Handle<Code> ic = is_classic_mode() |
| 4519 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 4501 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 4520 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 4502 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 4521 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); | 4503 CallIC(ic, NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); |
| 4522 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4504 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4523 if (expr->is_postfix()) { | 4505 if (expr->is_postfix()) { |
| 4524 if (!context()->IsEffect()) { | 4506 if (!context()->IsEffect()) { |
| 4525 context()->PlugTOS(); | 4507 context()->PlugTOS(); |
| 4526 } | 4508 } |
| 4527 } else { | 4509 } else { |
| 4528 context()->Plug(v0); | 4510 context()->Plug(v0); |
| 4529 } | 4511 } |
| 4530 break; | 4512 break; |
| 4531 } | 4513 } |
| 4532 } | 4514 } |
| 4533 } | 4515 } |
| 4534 | 4516 |
| 4535 | 4517 |
| 4536 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 4518 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
| 4537 ASSERT(!context()->IsEffect()); | 4519 ASSERT(!context()->IsEffect()); |
| 4538 ASSERT(!context()->IsTest()); | 4520 ASSERT(!context()->IsTest()); |
| 4539 VariableProxy* proxy = expr->AsVariableProxy(); | 4521 VariableProxy* proxy = expr->AsVariableProxy(); |
| 4540 if (proxy != NULL && proxy->var()->IsUnallocated()) { | 4522 if (proxy != NULL && proxy->var()->IsUnallocated()) { |
| 4541 Comment cmnt(masm_, "Global variable"); | 4523 Comment cmnt(masm_, "Global variable"); |
| 4542 __ lw(a0, GlobalObjectOperand()); | 4524 __ lw(a0, GlobalObjectOperand()); |
| 4543 __ li(a2, Operand(proxy->name())); | 4525 __ li(a2, Operand(proxy->name())); |
| 4544 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | |
| 4545 // Use a regular load, not a contextual load, to avoid a reference | 4526 // Use a regular load, not a contextual load, to avoid a reference |
| 4546 // error. | 4527 // error. |
| 4547 CallIC(ic); | 4528 CallLoadIC(NOT_CONTEXTUAL); |
| 4548 PrepareForBailout(expr, TOS_REG); | 4529 PrepareForBailout(expr, TOS_REG); |
| 4549 context()->Plug(v0); | 4530 context()->Plug(v0); |
| 4550 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 4531 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
| 4551 Label done, slow; | 4532 Label done, slow; |
| 4552 | 4533 |
| 4553 // Generate code for loading from variables potentially shadowed | 4534 // Generate code for loading from variables potentially shadowed |
| 4554 // by eval-introduced variables. | 4535 // by eval-introduced variables. |
| 4555 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); | 4536 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); |
| 4556 | 4537 |
| 4557 __ bind(&slow); | 4538 __ bind(&slow); |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4697 if (inline_smi_code) { | 4678 if (inline_smi_code) { |
| 4698 Label slow_case; | 4679 Label slow_case; |
| 4699 __ Or(a2, a0, Operand(a1)); | 4680 __ Or(a2, a0, Operand(a1)); |
| 4700 patch_site.EmitJumpIfNotSmi(a2, &slow_case); | 4681 patch_site.EmitJumpIfNotSmi(a2, &slow_case); |
| 4701 Split(cc, a1, Operand(a0), if_true, if_false, NULL); | 4682 Split(cc, a1, Operand(a0), if_true, if_false, NULL); |
| 4702 __ bind(&slow_case); | 4683 __ bind(&slow_case); |
| 4703 } | 4684 } |
| 4704 // Record position and call the compare IC. | 4685 // Record position and call the compare IC. |
| 4705 SetSourcePosition(expr->position()); | 4686 SetSourcePosition(expr->position()); |
| 4706 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); | 4687 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); |
| 4707 CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); | 4688 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); |
| 4708 patch_site.EmitPatchInfo(); | 4689 patch_site.EmitPatchInfo(); |
| 4709 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4690 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 4710 Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through); | 4691 Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through); |
| 4711 } | 4692 } |
| 4712 } | 4693 } |
| 4713 | 4694 |
| 4714 // Convert the result of the comparison into one expected for this | 4695 // Convert the result of the comparison into one expected for this |
| 4715 // expression's context. | 4696 // expression's context. |
| 4716 context()->Plug(if_true, if_false); | 4697 context()->Plug(if_true, if_false); |
| 4717 } | 4698 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 4731 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4712 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 4732 __ mov(a0, result_register()); | 4713 __ mov(a0, result_register()); |
| 4733 if (expr->op() == Token::EQ_STRICT) { | 4714 if (expr->op() == Token::EQ_STRICT) { |
| 4734 Heap::RootListIndex nil_value = nil == kNullValue ? | 4715 Heap::RootListIndex nil_value = nil == kNullValue ? |
| 4735 Heap::kNullValueRootIndex : | 4716 Heap::kNullValueRootIndex : |
| 4736 Heap::kUndefinedValueRootIndex; | 4717 Heap::kUndefinedValueRootIndex; |
| 4737 __ LoadRoot(a1, nil_value); | 4718 __ LoadRoot(a1, nil_value); |
| 4738 Split(eq, a0, Operand(a1), if_true, if_false, fall_through); | 4719 Split(eq, a0, Operand(a1), if_true, if_false, fall_through); |
| 4739 } else { | 4720 } else { |
| 4740 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); | 4721 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); |
| 4741 CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); | 4722 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); |
| 4742 Split(ne, v0, Operand(zero_reg), if_true, if_false, fall_through); | 4723 Split(ne, v0, Operand(zero_reg), if_true, if_false, fall_through); |
| 4743 } | 4724 } |
| 4744 context()->Plug(if_true, if_false); | 4725 context()->Plug(if_true, if_false); |
| 4745 } | 4726 } |
| 4746 | 4727 |
| 4747 | 4728 |
| 4748 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { | 4729 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { |
| 4749 __ lw(v0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 4730 __ lw(v0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 4750 context()->Plug(v0); | 4731 context()->Plug(v0); |
| 4751 } | 4732 } |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4969 Assembler::target_address_at(pc_immediate_load_address)) == | 4950 Assembler::target_address_at(pc_immediate_load_address)) == |
| 4970 reinterpret_cast<uint32_t>( | 4951 reinterpret_cast<uint32_t>( |
| 4971 isolate->builtins()->OsrAfterStackCheck()->entry())); | 4952 isolate->builtins()->OsrAfterStackCheck()->entry())); |
| 4972 return OSR_AFTER_STACK_CHECK; | 4953 return OSR_AFTER_STACK_CHECK; |
| 4973 } | 4954 } |
| 4974 | 4955 |
| 4975 | 4956 |
| 4976 } } // namespace v8::internal | 4957 } } // namespace v8::internal |
| 4977 | 4958 |
| 4978 #endif // V8_TARGET_ARCH_MIPS | 4959 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |