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 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 if (false_label_ != fall_through_) __ b(false_label_); | 654 if (false_label_ != fall_through_) __ b(false_label_); |
655 } | 655 } |
656 } | 656 } |
657 | 657 |
658 | 658 |
659 void FullCodeGenerator::DoTest(Expression* condition, | 659 void FullCodeGenerator::DoTest(Expression* condition, |
660 Label* if_true, | 660 Label* if_true, |
661 Label* if_false, | 661 Label* if_false, |
662 Label* fall_through) { | 662 Label* fall_through) { |
663 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); | 663 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); |
664 CallIC(ic, RelocInfo::CODE_TARGET, condition->test_id()); | 664 CallIC(ic, NOT_CONTEXTUAL, condition->test_id()); |
665 __ tst(result_register(), result_register()); | 665 __ tst(result_register(), result_register()); |
666 Split(ne, if_true, if_false, fall_through); | 666 Split(ne, if_true, if_false, fall_through); |
667 } | 667 } |
668 | 668 |
669 | 669 |
670 void FullCodeGenerator::Split(Condition cond, | 670 void FullCodeGenerator::Split(Condition cond, |
671 Label* if_true, | 671 Label* if_true, |
672 Label* if_false, | 672 Label* if_false, |
673 Label* fall_through) { | 673 Label* fall_through) { |
674 if (if_false == fall_through) { | 674 if (if_false == fall_through) { |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1015 __ cmp(r1, r0); | 1015 __ cmp(r1, r0); |
1016 __ b(ne, &next_test); | 1016 __ b(ne, &next_test); |
1017 __ Drop(1); // Switch value is no longer needed. | 1017 __ Drop(1); // Switch value is no longer needed. |
1018 __ b(clause->body_target()); | 1018 __ b(clause->body_target()); |
1019 __ bind(&slow_case); | 1019 __ bind(&slow_case); |
1020 } | 1020 } |
1021 | 1021 |
1022 // Record position before stub call for type feedback. | 1022 // Record position before stub call for type feedback. |
1023 SetSourcePosition(clause->position()); | 1023 SetSourcePosition(clause->position()); |
1024 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); | 1024 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); |
1025 CallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId()); | 1025 CallIC(ic, NOT_CONTEXTUAL, clause->CompareId()); |
1026 patch_site.EmitPatchInfo(); | 1026 patch_site.EmitPatchInfo(); |
1027 | 1027 |
1028 __ cmp(r0, Operand::Zero()); | 1028 __ cmp(r0, Operand::Zero()); |
1029 __ b(ne, &next_test); | 1029 __ b(ne, &next_test); |
1030 __ Drop(1); // Switch value is no longer needed. | 1030 __ Drop(1); // Switch value is no longer needed. |
1031 __ b(clause->body_target()); | 1031 __ b(clause->body_target()); |
1032 } | 1032 } |
1033 | 1033 |
1034 // Discard the test value and jump to the default if present, otherwise to | 1034 // Discard the test value and jump to the default if present, otherwise to |
1035 // the end of the statement. | 1035 // the end of the statement. |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1373 __ tst(temp, temp); | 1373 __ tst(temp, temp); |
1374 __ b(ne, slow); | 1374 __ b(ne, slow); |
1375 // Load next context in chain. | 1375 // Load next context in chain. |
1376 __ ldr(next, ContextOperand(next, Context::PREVIOUS_INDEX)); | 1376 __ ldr(next, ContextOperand(next, Context::PREVIOUS_INDEX)); |
1377 __ b(&loop); | 1377 __ b(&loop); |
1378 __ bind(&fast); | 1378 __ bind(&fast); |
1379 } | 1379 } |
1380 | 1380 |
1381 __ ldr(r0, GlobalObjectOperand()); | 1381 __ ldr(r0, GlobalObjectOperand()); |
1382 __ mov(r2, Operand(var->name())); | 1382 __ mov(r2, Operand(var->name())); |
1383 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 1383 ContextualMode mode = (typeof_state == INSIDE_TYPEOF) |
1384 ? RelocInfo::CODE_TARGET | 1384 ? NOT_CONTEXTUAL |
1385 : RelocInfo::CODE_TARGET_CONTEXT; | 1385 : CONTEXTUAL; |
1386 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1386 CallLoadIC(mode); |
1387 CallIC(ic, mode); | |
1388 } | 1387 } |
1389 | 1388 |
1390 | 1389 |
1391 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1390 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
1392 Label* slow) { | 1391 Label* slow) { |
1393 ASSERT(var->IsContextSlot()); | 1392 ASSERT(var->IsContextSlot()); |
1394 Register context = cp; | 1393 Register context = cp; |
1395 Register next = r3; | 1394 Register next = r3; |
1396 Register temp = r4; | 1395 Register temp = r4; |
1397 | 1396 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1460 | 1459 |
1461 // Three cases: global variables, lookup variables, and all other types of | 1460 // Three cases: global variables, lookup variables, and all other types of |
1462 // variables. | 1461 // variables. |
1463 switch (var->location()) { | 1462 switch (var->location()) { |
1464 case Variable::UNALLOCATED: { | 1463 case Variable::UNALLOCATED: { |
1465 Comment cmnt(masm_, "Global variable"); | 1464 Comment cmnt(masm_, "Global variable"); |
1466 // Use inline caching. Variable name is passed in r2 and the global | 1465 // Use inline caching. Variable name is passed in r2 and the global |
1467 // object (receiver) in r0. | 1466 // object (receiver) in r0. |
1468 __ ldr(r0, GlobalObjectOperand()); | 1467 __ ldr(r0, GlobalObjectOperand()); |
1469 __ mov(r2, Operand(var->name())); | 1468 __ mov(r2, Operand(var->name())); |
1470 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1469 CallLoadIC(CONTEXTUAL); |
1471 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | |
1472 context()->Plug(r0); | 1470 context()->Plug(r0); |
1473 break; | 1471 break; |
1474 } | 1472 } |
1475 | 1473 |
1476 case Variable::PARAMETER: | 1474 case Variable::PARAMETER: |
1477 case Variable::LOCAL: | 1475 case Variable::LOCAL: |
1478 case Variable::CONTEXT: { | 1476 case Variable::CONTEXT: { |
1479 Comment cmnt(masm_, var->IsContextSlot() | 1477 Comment cmnt(masm_, var->IsContextSlot() |
1480 ? "Context variable" | 1478 ? "Context variable" |
1481 : "Stack variable"); | 1479 : "Stack variable"); |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1670 UNREACHABLE(); | 1668 UNREACHABLE(); |
1671 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1669 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1672 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1670 ASSERT(!CompileTimeValue::IsCompileTimeValue(property->value())); |
1673 // Fall through. | 1671 // Fall through. |
1674 case ObjectLiteral::Property::COMPUTED: | 1672 case ObjectLiteral::Property::COMPUTED: |
1675 if (key->value()->IsInternalizedString()) { | 1673 if (key->value()->IsInternalizedString()) { |
1676 if (property->emit_store()) { | 1674 if (property->emit_store()) { |
1677 VisitForAccumulatorValue(value); | 1675 VisitForAccumulatorValue(value); |
1678 __ mov(r2, Operand(key->value())); | 1676 __ mov(r2, Operand(key->value())); |
1679 __ ldr(r1, MemOperand(sp)); | 1677 __ ldr(r1, MemOperand(sp)); |
1680 Handle<Code> ic = is_classic_mode() | 1678 CallStoreIC(NOT_CONTEXTUAL, key->LiteralFeedbackId()); |
1681 ? isolate()->builtins()->StoreIC_Initialize() | |
1682 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
1683 CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId()); | |
1684 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1679 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
1685 } else { | 1680 } else { |
1686 VisitForEffect(value); | 1681 VisitForEffect(value); |
1687 } | 1682 } |
1688 break; | 1683 break; |
1689 } | 1684 } |
1690 // Duplicate receiver on stack. | 1685 // Duplicate receiver on stack. |
1691 __ ldr(r0, MemOperand(sp)); | 1686 __ ldr(r0, MemOperand(sp)); |
1692 __ push(r0); | 1687 __ push(r0); |
1693 VisitForStackValue(key); | 1688 VisitForStackValue(key); |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2081 // result = receiver[f](arg); | 2076 // result = receiver[f](arg); |
2082 __ bind(&l_call); | 2077 __ bind(&l_call); |
2083 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); | 2078 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); |
2084 CallIC(ic); | 2079 CallIC(ic); |
2085 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2080 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2086 | 2081 |
2087 // if (!result.done) goto l_try; | 2082 // if (!result.done) goto l_try; |
2088 __ bind(&l_loop); | 2083 __ bind(&l_loop); |
2089 __ push(r0); // save result | 2084 __ push(r0); // save result |
2090 __ LoadRoot(r2, Heap::kdone_stringRootIndex); // "done" | 2085 __ LoadRoot(r2, Heap::kdone_stringRootIndex); // "done" |
2091 Handle<Code> done_ic = isolate()->builtins()->LoadIC_Initialize(); | 2086 CallLoadIC(NOT_CONTEXTUAL); // result.done in r0 |
2092 CallIC(done_ic); // result.done in r0 | |
2093 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); | 2087 Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); |
2094 CallIC(bool_ic); | 2088 CallIC(bool_ic); |
2095 __ cmp(r0, Operand(0)); | 2089 __ cmp(r0, Operand(0)); |
2096 __ b(eq, &l_try); | 2090 __ b(eq, &l_try); |
2097 | 2091 |
2098 // result.value | 2092 // result.value |
2099 __ pop(r0); // result | 2093 __ pop(r0); // result |
2100 __ LoadRoot(r2, Heap::kvalue_stringRootIndex); // "value" | 2094 __ LoadRoot(r2, Heap::kvalue_stringRootIndex); // "value" |
2101 Handle<Code> value_ic = isolate()->builtins()->LoadIC_Initialize(); | 2095 CallLoadIC(NOT_CONTEXTUAL); // result.value in r0 |
2102 CallIC(value_ic); // result.value in r0 | |
2103 context()->DropAndPlug(2, r0); // drop iter and g | 2096 context()->DropAndPlug(2, r0); // drop iter and g |
2104 break; | 2097 break; |
2105 } | 2098 } |
2106 } | 2099 } |
2107 } | 2100 } |
2108 | 2101 |
2109 | 2102 |
2110 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, | 2103 void FullCodeGenerator::EmitGeneratorResume(Expression *generator, |
2111 Expression *value, | 2104 Expression *value, |
2112 JSGeneratorObject::ResumeMode resume_mode) { | 2105 JSGeneratorObject::ResumeMode resume_mode) { |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2241 __ RecordWriteField(r0, JSGeneratorObject::kResultValuePropertyOffset, | 2234 __ RecordWriteField(r0, JSGeneratorObject::kResultValuePropertyOffset, |
2242 r2, r3, kLRHasBeenSaved, kDontSaveFPRegs); | 2235 r2, r3, kLRHasBeenSaved, kDontSaveFPRegs); |
2243 } | 2236 } |
2244 | 2237 |
2245 | 2238 |
2246 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2239 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
2247 SetSourcePosition(prop->position()); | 2240 SetSourcePosition(prop->position()); |
2248 Literal* key = prop->key()->AsLiteral(); | 2241 Literal* key = prop->key()->AsLiteral(); |
2249 __ mov(r2, Operand(key->value())); | 2242 __ mov(r2, Operand(key->value())); |
2250 // Call load IC. It has arguments receiver and property name r0 and r2. | 2243 // Call load IC. It has arguments receiver and property name r0 and r2. |
2251 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 2244 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
2252 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); | |
2253 } | 2245 } |
2254 | 2246 |
2255 | 2247 |
2256 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2248 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
2257 SetSourcePosition(prop->position()); | 2249 SetSourcePosition(prop->position()); |
2258 // Call keyed load IC. It has arguments key and receiver in r0 and r1. | 2250 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
2259 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2251 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
2260 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); | 2252 CallIC(ic, NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
2261 } | 2253 } |
2262 | 2254 |
2263 | 2255 |
2264 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2256 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
2265 Token::Value op, | 2257 Token::Value op, |
2266 OverwriteMode mode, | 2258 OverwriteMode mode, |
2267 Expression* left_expr, | 2259 Expression* left_expr, |
2268 Expression* right_expr) { | 2260 Expression* right_expr) { |
2269 Label done, smi_case, stub_call; | 2261 Label done, smi_case, stub_call; |
2270 | 2262 |
2271 Register scratch1 = r2; | 2263 Register scratch1 = r2; |
2272 Register scratch2 = r3; | 2264 Register scratch2 = r3; |
2273 | 2265 |
2274 // Get the arguments. | 2266 // Get the arguments. |
2275 Register left = r1; | 2267 Register left = r1; |
2276 Register right = r0; | 2268 Register right = r0; |
2277 __ pop(left); | 2269 __ pop(left); |
2278 | 2270 |
2279 // Perform combined smi check on both operands. | 2271 // Perform combined smi check on both operands. |
2280 __ orr(scratch1, left, Operand(right)); | 2272 __ orr(scratch1, left, Operand(right)); |
2281 STATIC_ASSERT(kSmiTag == 0); | 2273 STATIC_ASSERT(kSmiTag == 0); |
2282 JumpPatchSite patch_site(masm_); | 2274 JumpPatchSite patch_site(masm_); |
2283 patch_site.EmitJumpIfSmi(scratch1, &smi_case); | 2275 patch_site.EmitJumpIfSmi(scratch1, &smi_case); |
2284 | 2276 |
2285 __ bind(&stub_call); | 2277 __ bind(&stub_call); |
2286 BinaryOpICStub stub(op, mode); | 2278 BinaryOpICStub stub(op, mode); |
2287 CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, | 2279 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, |
2288 expr->BinaryOperationFeedbackId()); | 2280 expr->BinaryOperationFeedbackId()); |
2289 patch_site.EmitPatchInfo(); | 2281 patch_site.EmitPatchInfo(); |
2290 __ jmp(&done); | 2282 __ jmp(&done); |
2291 | 2283 |
2292 __ bind(&smi_case); | 2284 __ bind(&smi_case); |
2293 // Smi case. This code works the same way as the smi-smi case in the type | 2285 // Smi case. This code works the same way as the smi-smi case in the type |
2294 // recording binary operation stub, see | 2286 // recording binary operation stub, see |
2295 switch (op) { | 2287 switch (op) { |
2296 case Token::SAR: | 2288 case Token::SAR: |
2297 __ GetLeastBitsFromSmi(scratch1, right, 5); | 2289 __ GetLeastBitsFromSmi(scratch1, right, 5); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2355 context()->Plug(r0); | 2347 context()->Plug(r0); |
2356 } | 2348 } |
2357 | 2349 |
2358 | 2350 |
2359 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 2351 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
2360 Token::Value op, | 2352 Token::Value op, |
2361 OverwriteMode mode) { | 2353 OverwriteMode mode) { |
2362 __ pop(r1); | 2354 __ pop(r1); |
2363 BinaryOpICStub stub(op, mode); | 2355 BinaryOpICStub stub(op, mode); |
2364 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2356 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
2365 CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, | 2357 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL, |
2366 expr->BinaryOperationFeedbackId()); | 2358 expr->BinaryOperationFeedbackId()); |
2367 patch_site.EmitPatchInfo(); | 2359 patch_site.EmitPatchInfo(); |
2368 context()->Plug(r0); | 2360 context()->Plug(r0); |
2369 } | 2361 } |
2370 | 2362 |
2371 | 2363 |
2372 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2364 void FullCodeGenerator::EmitAssignment(Expression* expr) { |
2373 // Invalid left-hand sides are rewritten by the parser to have a 'throw | 2365 // Invalid left-hand sides are rewritten by the parser to have a 'throw |
2374 // ReferenceError' on the left-hand side. | 2366 // ReferenceError' on the left-hand side. |
2375 if (!expr->IsValidLeftHandSide()) { | 2367 if (!expr->IsValidLeftHandSide()) { |
(...skipping 18 matching lines...) Expand all Loading... |
2394 EffectContext context(this); | 2386 EffectContext context(this); |
2395 EmitVariableAssignment(var, Token::ASSIGN); | 2387 EmitVariableAssignment(var, Token::ASSIGN); |
2396 break; | 2388 break; |
2397 } | 2389 } |
2398 case NAMED_PROPERTY: { | 2390 case NAMED_PROPERTY: { |
2399 __ push(r0); // Preserve value. | 2391 __ push(r0); // Preserve value. |
2400 VisitForAccumulatorValue(prop->obj()); | 2392 VisitForAccumulatorValue(prop->obj()); |
2401 __ mov(r1, r0); | 2393 __ mov(r1, r0); |
2402 __ pop(r0); // Restore value. | 2394 __ pop(r0); // Restore value. |
2403 __ mov(r2, Operand(prop->key()->AsLiteral()->value())); | 2395 __ mov(r2, Operand(prop->key()->AsLiteral()->value())); |
2404 Handle<Code> ic = is_classic_mode() | 2396 CallStoreIC(NOT_CONTEXTUAL); |
2405 ? isolate()->builtins()->StoreIC_Initialize() | |
2406 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
2407 CallIC(ic); | |
2408 break; | 2397 break; |
2409 } | 2398 } |
2410 case KEYED_PROPERTY: { | 2399 case KEYED_PROPERTY: { |
2411 __ push(r0); // Preserve value. | 2400 __ push(r0); // Preserve value. |
2412 VisitForStackValue(prop->obj()); | 2401 VisitForStackValue(prop->obj()); |
2413 VisitForAccumulatorValue(prop->key()); | 2402 VisitForAccumulatorValue(prop->key()); |
2414 __ mov(r1, r0); | 2403 __ mov(r1, r0); |
2415 __ Pop(r0, r2); // r0 = restored value. | 2404 __ Pop(r0, r2); // r0 = restored value. |
2416 Handle<Code> ic = is_classic_mode() | 2405 Handle<Code> ic = is_classic_mode() |
2417 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2406 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
2418 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2407 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
2419 CallIC(ic); | 2408 CallIC(ic); |
2420 break; | 2409 break; |
2421 } | 2410 } |
2422 } | 2411 } |
2423 context()->Plug(r0); | 2412 context()->Plug(r0); |
2424 } | 2413 } |
2425 | 2414 |
2426 | 2415 |
2427 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 2416 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
2428 Token::Value op) { | 2417 Token::Value op) { |
2429 if (var->IsUnallocated()) { | 2418 if (var->IsUnallocated()) { |
2430 // Global var, const, or let. | 2419 // Global var, const, or let. |
2431 __ mov(r2, Operand(var->name())); | 2420 __ mov(r2, Operand(var->name())); |
2432 __ ldr(r1, GlobalObjectOperand()); | 2421 __ ldr(r1, GlobalObjectOperand()); |
2433 Handle<Code> ic = is_classic_mode() | 2422 CallStoreIC(CONTEXTUAL); |
2434 ? isolate()->builtins()->StoreIC_Initialize() | |
2435 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
2436 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | |
2437 | |
2438 } else if (op == Token::INIT_CONST) { | 2423 } else if (op == Token::INIT_CONST) { |
2439 // Const initializers need a write barrier. | 2424 // Const initializers need a write barrier. |
2440 ASSERT(!var->IsParameter()); // No const parameters. | 2425 ASSERT(!var->IsParameter()); // No const parameters. |
2441 if (var->IsStackLocal()) { | 2426 if (var->IsStackLocal()) { |
2442 Label skip; | 2427 Label skip; |
2443 __ ldr(r1, StackOperand(var)); | 2428 __ ldr(r1, StackOperand(var)); |
2444 __ CompareRoot(r1, Heap::kTheHoleValueRootIndex); | 2429 __ CompareRoot(r1, Heap::kTheHoleValueRootIndex); |
2445 __ b(ne, &skip); | 2430 __ b(ne, &skip); |
2446 __ str(result_register(), StackOperand(var)); | 2431 __ str(result_register(), StackOperand(var)); |
2447 __ bind(&skip); | 2432 __ bind(&skip); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2524 // Assignment to a property, using a named store IC. | 2509 // Assignment to a property, using a named store IC. |
2525 Property* prop = expr->target()->AsProperty(); | 2510 Property* prop = expr->target()->AsProperty(); |
2526 ASSERT(prop != NULL); | 2511 ASSERT(prop != NULL); |
2527 ASSERT(prop->key()->AsLiteral() != NULL); | 2512 ASSERT(prop->key()->AsLiteral() != NULL); |
2528 | 2513 |
2529 // Record source code position before IC call. | 2514 // Record source code position before IC call. |
2530 SetSourcePosition(expr->position()); | 2515 SetSourcePosition(expr->position()); |
2531 __ mov(r2, Operand(prop->key()->AsLiteral()->value())); | 2516 __ mov(r2, Operand(prop->key()->AsLiteral()->value())); |
2532 __ pop(r1); | 2517 __ pop(r1); |
2533 | 2518 |
2534 Handle<Code> ic = is_classic_mode() | 2519 CallStoreIC(NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); |
2535 ? isolate()->builtins()->StoreIC_Initialize() | |
2536 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
2537 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); | |
2538 | 2520 |
2539 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2521 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2540 context()->Plug(r0); | 2522 context()->Plug(r0); |
2541 } | 2523 } |
2542 | 2524 |
2543 | 2525 |
2544 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2526 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2545 // Assignment to a property, using a keyed store IC. | 2527 // Assignment to a property, using a keyed store IC. |
2546 | 2528 |
2547 // Record source code position before IC call. | 2529 // Record source code position before IC call. |
2548 SetSourcePosition(expr->position()); | 2530 SetSourcePosition(expr->position()); |
2549 __ Pop(r2, r1); // r1 = key. | 2531 __ Pop(r2, r1); // r1 = key. |
2550 | 2532 |
2551 Handle<Code> ic = is_classic_mode() | 2533 Handle<Code> ic = is_classic_mode() |
2552 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2534 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
2553 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2535 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
2554 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); | 2536 CallIC(ic, NOT_CONTEXTUAL, expr->AssignmentFeedbackId()); |
2555 | 2537 |
2556 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2538 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2557 context()->Plug(r0); | 2539 context()->Plug(r0); |
2558 } | 2540 } |
2559 | 2541 |
2560 | 2542 |
2561 void FullCodeGenerator::VisitProperty(Property* expr) { | 2543 void FullCodeGenerator::VisitProperty(Property* expr) { |
2562 Comment cmnt(masm_, "[ Property"); | 2544 Comment cmnt(masm_, "[ Property"); |
2563 Expression* key = expr->key(); | 2545 Expression* key = expr->key(); |
2564 | 2546 |
2565 if (key->IsPropertyName()) { | 2547 if (key->IsPropertyName()) { |
2566 VisitForAccumulatorValue(expr->obj()); | 2548 VisitForAccumulatorValue(expr->obj()); |
2567 EmitNamedPropertyLoad(expr); | 2549 EmitNamedPropertyLoad(expr); |
2568 PrepareForBailoutForId(expr->LoadId(), TOS_REG); | 2550 PrepareForBailoutForId(expr->LoadId(), TOS_REG); |
2569 context()->Plug(r0); | 2551 context()->Plug(r0); |
2570 } else { | 2552 } else { |
2571 VisitForStackValue(expr->obj()); | 2553 VisitForStackValue(expr->obj()); |
2572 VisitForAccumulatorValue(expr->key()); | 2554 VisitForAccumulatorValue(expr->key()); |
2573 __ pop(r1); | 2555 __ pop(r1); |
2574 EmitKeyedPropertyLoad(expr); | 2556 EmitKeyedPropertyLoad(expr); |
2575 context()->Plug(r0); | 2557 context()->Plug(r0); |
2576 } | 2558 } |
2577 } | 2559 } |
2578 | 2560 |
2579 | 2561 |
2580 void FullCodeGenerator::CallIC(Handle<Code> code, | 2562 void FullCodeGenerator::CallIC(Handle<Code> code, |
2581 RelocInfo::Mode rmode, | 2563 ContextualMode mode, |
2582 TypeFeedbackId ast_id) { | 2564 TypeFeedbackId ast_id) { |
2583 ic_total_count_++; | 2565 ic_total_count_++; |
2584 // All calls must have a predictable size in full-codegen code to ensure that | 2566 // All calls must have a predictable size in full-codegen code to ensure that |
2585 // the debugger can patch them correctly. | 2567 // the debugger can patch them correctly. |
2586 __ Call(code, rmode, ast_id, al, NEVER_INLINE_TARGET_ADDRESS); | 2568 ASSERT(mode != CONTEXTUAL || ast_id.IsNone()); |
| 2569 __ Call(code, RelocInfo::CODE_TARGET, ast_id, al, |
| 2570 NEVER_INLINE_TARGET_ADDRESS); |
2587 } | 2571 } |
2588 | 2572 |
2589 void FullCodeGenerator::EmitCallWithIC(Call* expr, | 2573 void FullCodeGenerator::EmitCallWithIC(Call* expr, |
2590 Handle<Object> name, | 2574 Handle<Object> name, |
2591 RelocInfo::Mode mode) { | 2575 ContextualMode mode) { |
2592 // Code common for calls using the IC. | 2576 // Code common for calls using the IC. |
2593 ZoneList<Expression*>* args = expr->arguments(); | 2577 ZoneList<Expression*>* args = expr->arguments(); |
2594 int arg_count = args->length(); | 2578 int arg_count = args->length(); |
2595 { PreservePositionScope scope(masm()->positions_recorder()); | 2579 { PreservePositionScope scope(masm()->positions_recorder()); |
2596 for (int i = 0; i < arg_count; i++) { | 2580 for (int i = 0; i < arg_count; i++) { |
2597 VisitForStackValue(args->at(i)); | 2581 VisitForStackValue(args->at(i)); |
2598 } | 2582 } |
2599 __ mov(r2, Operand(name)); | 2583 __ mov(r2, Operand(name)); |
2600 } | 2584 } |
2601 // Record source position for debugger. | 2585 // Record source position for debugger. |
2602 SetSourcePosition(expr->position()); | 2586 SetSourcePosition(expr->position()); |
2603 // Call the IC initialization code. | 2587 // Call the IC initialization code. |
2604 Handle<Code> ic = | 2588 Handle<Code> ic = |
2605 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 2589 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
2606 CallIC(ic, mode, expr->CallFeedbackId()); | 2590 TypeFeedbackId ast_id = mode == CONTEXTUAL |
| 2591 ? TypeFeedbackId::None() |
| 2592 : expr->CallFeedbackId(); |
| 2593 CallIC(ic, mode, ast_id); |
2607 RecordJSReturnSite(expr); | 2594 RecordJSReturnSite(expr); |
2608 // Restore context register. | 2595 // Restore context register. |
2609 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2596 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2610 context()->Plug(r0); | 2597 context()->Plug(r0); |
2611 } | 2598 } |
2612 | 2599 |
2613 | 2600 |
2614 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 2601 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
2615 Expression* key) { | 2602 Expression* key) { |
2616 // Load the key. | 2603 // Load the key. |
(...skipping 12 matching lines...) Expand all Loading... |
2629 for (int i = 0; i < arg_count; i++) { | 2616 for (int i = 0; i < arg_count; i++) { |
2630 VisitForStackValue(args->at(i)); | 2617 VisitForStackValue(args->at(i)); |
2631 } | 2618 } |
2632 } | 2619 } |
2633 // Record source position for debugger. | 2620 // Record source position for debugger. |
2634 SetSourcePosition(expr->position()); | 2621 SetSourcePosition(expr->position()); |
2635 // Call the IC initialization code. | 2622 // Call the IC initialization code. |
2636 Handle<Code> ic = | 2623 Handle<Code> ic = |
2637 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); | 2624 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); |
2638 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. | 2625 __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. |
2639 CallIC(ic, RelocInfo::CODE_TARGET, expr->CallFeedbackId()); | 2626 CallIC(ic, NOT_CONTEXTUAL, expr->CallFeedbackId()); |
2640 RecordJSReturnSite(expr); | 2627 RecordJSReturnSite(expr); |
2641 // Restore context register. | 2628 // Restore context register. |
2642 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2629 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2643 context()->DropAndPlug(1, r0); // Drop the key still on the stack. | 2630 context()->DropAndPlug(1, r0); // Drop the key still on the stack. |
2644 } | 2631 } |
2645 | 2632 |
2646 | 2633 |
2647 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { | 2634 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { |
2648 // Code common for calls using the call stub. | 2635 // Code common for calls using the call stub. |
2649 ZoneList<Expression*>* args = expr->arguments(); | 2636 ZoneList<Expression*>* args = expr->arguments(); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2746 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2733 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
2747 __ CallStub(&stub); | 2734 __ CallStub(&stub); |
2748 RecordJSReturnSite(expr); | 2735 RecordJSReturnSite(expr); |
2749 // Restore context register. | 2736 // Restore context register. |
2750 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2737 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2751 context()->DropAndPlug(1, r0); | 2738 context()->DropAndPlug(1, r0); |
2752 } else if (proxy != NULL && proxy->var()->IsUnallocated()) { | 2739 } else if (proxy != NULL && proxy->var()->IsUnallocated()) { |
2753 // Push global object as receiver for the call IC. | 2740 // Push global object as receiver for the call IC. |
2754 __ ldr(r0, GlobalObjectOperand()); | 2741 __ ldr(r0, GlobalObjectOperand()); |
2755 __ push(r0); | 2742 __ push(r0); |
2756 EmitCallWithIC(expr, proxy->name(), RelocInfo::CODE_TARGET_CONTEXT); | 2743 EmitCallWithIC(expr, proxy->name(), CONTEXTUAL); |
2757 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 2744 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
2758 // Call to a lookup slot (dynamically introduced variable). | 2745 // Call to a lookup slot (dynamically introduced variable). |
2759 Label slow, done; | 2746 Label slow, done; |
2760 | 2747 |
2761 { PreservePositionScope scope(masm()->positions_recorder()); | 2748 { PreservePositionScope scope(masm()->positions_recorder()); |
2762 // Generate code for loading from variables potentially shadowed | 2749 // Generate code for loading from variables potentially shadowed |
2763 // by eval-introduced variables. | 2750 // by eval-introduced variables. |
2764 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); | 2751 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); |
2765 } | 2752 } |
2766 | 2753 |
(...skipping 26 matching lines...) Expand all Loading... |
2793 // by LoadContextSlot. That object could be the hole if the | 2780 // by LoadContextSlot. That object could be the hole if the |
2794 // receiver is implicitly the global object. | 2781 // receiver is implicitly the global object. |
2795 EmitCallWithStub(expr, RECEIVER_MIGHT_BE_IMPLICIT); | 2782 EmitCallWithStub(expr, RECEIVER_MIGHT_BE_IMPLICIT); |
2796 } else if (property != NULL) { | 2783 } else if (property != NULL) { |
2797 { PreservePositionScope scope(masm()->positions_recorder()); | 2784 { PreservePositionScope scope(masm()->positions_recorder()); |
2798 VisitForStackValue(property->obj()); | 2785 VisitForStackValue(property->obj()); |
2799 } | 2786 } |
2800 if (property->key()->IsPropertyName()) { | 2787 if (property->key()->IsPropertyName()) { |
2801 EmitCallWithIC(expr, | 2788 EmitCallWithIC(expr, |
2802 property->key()->AsLiteral()->value(), | 2789 property->key()->AsLiteral()->value(), |
2803 RelocInfo::CODE_TARGET); | 2790 NOT_CONTEXTUAL); |
2804 } else { | 2791 } else { |
2805 EmitKeyedCallWithIC(expr, property->key()); | 2792 EmitKeyedCallWithIC(expr, property->key()); |
2806 } | 2793 } |
2807 } else { | 2794 } else { |
2808 // Call to an arbitrary expression not handled specially above. | 2795 // Call to an arbitrary expression not handled specially above. |
2809 { PreservePositionScope scope(masm()->positions_recorder()); | 2796 { PreservePositionScope scope(masm()->positions_recorder()); |
2810 VisitForStackValue(callee); | 2797 VisitForStackValue(callee); |
2811 } | 2798 } |
2812 // Load global receiver object. | 2799 // Load global receiver object. |
2813 __ ldr(r1, GlobalObjectOperand()); | 2800 __ ldr(r1, GlobalObjectOperand()); |
(...skipping 1330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4144 | 4131 |
4145 // Push the arguments ("left-to-right"). | 4132 // Push the arguments ("left-to-right"). |
4146 int arg_count = args->length(); | 4133 int arg_count = args->length(); |
4147 for (int i = 0; i < arg_count; i++) { | 4134 for (int i = 0; i < arg_count; i++) { |
4148 VisitForStackValue(args->at(i)); | 4135 VisitForStackValue(args->at(i)); |
4149 } | 4136 } |
4150 | 4137 |
4151 if (expr->is_jsruntime()) { | 4138 if (expr->is_jsruntime()) { |
4152 // Call the JS runtime function. | 4139 // Call the JS runtime function. |
4153 __ mov(r2, Operand(expr->name())); | 4140 __ mov(r2, Operand(expr->name())); |
4154 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; | 4141 ContextualMode mode = NOT_CONTEXTUAL; |
4155 Handle<Code> ic = | 4142 Handle<Code> ic = |
4156 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); | 4143 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); |
4157 CallIC(ic, mode, expr->CallRuntimeFeedbackId()); | 4144 CallIC(ic, mode, expr->CallRuntimeFeedbackId()); |
4158 // Restore context register. | 4145 // Restore context register. |
4159 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4146 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
4160 } else { | 4147 } else { |
4161 // Call the C runtime function. | 4148 // Call the C runtime function. |
4162 __ CallRuntime(expr->function(), arg_count); | 4149 __ CallRuntime(expr->function(), arg_count); |
4163 } | 4150 } |
4164 context()->Plug(r0); | 4151 context()->Plug(r0); |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4395 | 4382 |
4396 __ bind(&stub_call); | 4383 __ bind(&stub_call); |
4397 __ mov(r1, r0); | 4384 __ mov(r1, r0); |
4398 __ mov(r0, Operand(Smi::FromInt(count_value))); | 4385 __ mov(r0, Operand(Smi::FromInt(count_value))); |
4399 | 4386 |
4400 // Record position before stub call. | 4387 // Record position before stub call. |
4401 SetSourcePosition(expr->position()); | 4388 SetSourcePosition(expr->position()); |
4402 | 4389 |
4403 BinaryOpICStub stub(Token::ADD, NO_OVERWRITE); | 4390 BinaryOpICStub stub(Token::ADD, NO_OVERWRITE); |
4404 CallIC(stub.GetCode(isolate()), | 4391 CallIC(stub.GetCode(isolate()), |
4405 RelocInfo::CODE_TARGET, | 4392 NOT_CONTEXTUAL, |
4406 expr->CountBinOpFeedbackId()); | 4393 expr->CountBinOpFeedbackId()); |
4407 patch_site.EmitPatchInfo(); | 4394 patch_site.EmitPatchInfo(); |
4408 __ bind(&done); | 4395 __ bind(&done); |
4409 | 4396 |
4410 // Store the value returned in r0. | 4397 // Store the value returned in r0. |
4411 switch (assign_type) { | 4398 switch (assign_type) { |
4412 case VARIABLE: | 4399 case VARIABLE: |
4413 if (expr->is_postfix()) { | 4400 if (expr->is_postfix()) { |
4414 { EffectContext context(this); | 4401 { EffectContext context(this); |
4415 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4402 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
4416 Token::ASSIGN); | 4403 Token::ASSIGN); |
4417 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4404 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4418 context.Plug(r0); | 4405 context.Plug(r0); |
4419 } | 4406 } |
4420 // For all contexts except EffectConstant We have the result on | 4407 // For all contexts except EffectConstant We have the result on |
4421 // top of the stack. | 4408 // top of the stack. |
4422 if (!context()->IsEffect()) { | 4409 if (!context()->IsEffect()) { |
4423 context()->PlugTOS(); | 4410 context()->PlugTOS(); |
4424 } | 4411 } |
4425 } else { | 4412 } else { |
4426 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4413 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
4427 Token::ASSIGN); | 4414 Token::ASSIGN); |
4428 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4415 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4429 context()->Plug(r0); | 4416 context()->Plug(r0); |
4430 } | 4417 } |
4431 break; | 4418 break; |
4432 case NAMED_PROPERTY: { | 4419 case NAMED_PROPERTY: { |
4433 __ mov(r2, Operand(prop->key()->AsLiteral()->value())); | 4420 __ mov(r2, Operand(prop->key()->AsLiteral()->value())); |
4434 __ pop(r1); | 4421 __ pop(r1); |
4435 Handle<Code> ic = is_classic_mode() | 4422 CallStoreIC(NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); |
4436 ? isolate()->builtins()->StoreIC_Initialize() | |
4437 : isolate()->builtins()->StoreIC_Initialize_Strict(); | |
4438 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); | |
4439 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4423 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4440 if (expr->is_postfix()) { | 4424 if (expr->is_postfix()) { |
4441 if (!context()->IsEffect()) { | 4425 if (!context()->IsEffect()) { |
4442 context()->PlugTOS(); | 4426 context()->PlugTOS(); |
4443 } | 4427 } |
4444 } else { | 4428 } else { |
4445 context()->Plug(r0); | 4429 context()->Plug(r0); |
4446 } | 4430 } |
4447 break; | 4431 break; |
4448 } | 4432 } |
4449 case KEYED_PROPERTY: { | 4433 case KEYED_PROPERTY: { |
4450 __ Pop(r2, r1); // r1 = key. r2 = receiver. | 4434 __ Pop(r2, r1); // r1 = key. r2 = receiver. |
4451 Handle<Code> ic = is_classic_mode() | 4435 Handle<Code> ic = is_classic_mode() |
4452 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 4436 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
4453 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 4437 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
4454 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); | 4438 CallIC(ic, NOT_CONTEXTUAL, expr->CountStoreFeedbackId()); |
4455 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4439 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4456 if (expr->is_postfix()) { | 4440 if (expr->is_postfix()) { |
4457 if (!context()->IsEffect()) { | 4441 if (!context()->IsEffect()) { |
4458 context()->PlugTOS(); | 4442 context()->PlugTOS(); |
4459 } | 4443 } |
4460 } else { | 4444 } else { |
4461 context()->Plug(r0); | 4445 context()->Plug(r0); |
4462 } | 4446 } |
4463 break; | 4447 break; |
4464 } | 4448 } |
4465 } | 4449 } |
4466 } | 4450 } |
4467 | 4451 |
4468 | 4452 |
4469 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 4453 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
4470 ASSERT(!context()->IsEffect()); | 4454 ASSERT(!context()->IsEffect()); |
4471 ASSERT(!context()->IsTest()); | 4455 ASSERT(!context()->IsTest()); |
4472 VariableProxy* proxy = expr->AsVariableProxy(); | 4456 VariableProxy* proxy = expr->AsVariableProxy(); |
4473 if (proxy != NULL && proxy->var()->IsUnallocated()) { | 4457 if (proxy != NULL && proxy->var()->IsUnallocated()) { |
4474 Comment cmnt(masm_, "Global variable"); | 4458 Comment cmnt(masm_, "Global variable"); |
4475 __ ldr(r0, GlobalObjectOperand()); | 4459 __ ldr(r0, GlobalObjectOperand()); |
4476 __ mov(r2, Operand(proxy->name())); | 4460 __ mov(r2, Operand(proxy->name())); |
4477 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | |
4478 // Use a regular load, not a contextual load, to avoid a reference | 4461 // Use a regular load, not a contextual load, to avoid a reference |
4479 // error. | 4462 // error. |
4480 CallIC(ic); | 4463 CallLoadIC(NOT_CONTEXTUAL); |
4481 PrepareForBailout(expr, TOS_REG); | 4464 PrepareForBailout(expr, TOS_REG); |
4482 context()->Plug(r0); | 4465 context()->Plug(r0); |
4483 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 4466 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
4484 Label done, slow; | 4467 Label done, slow; |
4485 | 4468 |
4486 // Generate code for loading from variables potentially shadowed | 4469 // Generate code for loading from variables potentially shadowed |
4487 // by eval-introduced variables. | 4470 // by eval-introduced variables. |
4488 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); | 4471 EmitDynamicLookupFastCase(proxy->var(), INSIDE_TYPEOF, &slow, &done); |
4489 | 4472 |
4490 __ bind(&slow); | 4473 __ bind(&slow); |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4635 __ orr(r2, r0, Operand(r1)); | 4618 __ orr(r2, r0, Operand(r1)); |
4636 patch_site.EmitJumpIfNotSmi(r2, &slow_case); | 4619 patch_site.EmitJumpIfNotSmi(r2, &slow_case); |
4637 __ cmp(r1, r0); | 4620 __ cmp(r1, r0); |
4638 Split(cond, if_true, if_false, NULL); | 4621 Split(cond, if_true, if_false, NULL); |
4639 __ bind(&slow_case); | 4622 __ bind(&slow_case); |
4640 } | 4623 } |
4641 | 4624 |
4642 // Record position and call the compare IC. | 4625 // Record position and call the compare IC. |
4643 SetSourcePosition(expr->position()); | 4626 SetSourcePosition(expr->position()); |
4644 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); | 4627 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); |
4645 CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); | 4628 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); |
4646 patch_site.EmitPatchInfo(); | 4629 patch_site.EmitPatchInfo(); |
4647 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4630 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
4648 __ cmp(r0, Operand::Zero()); | 4631 __ cmp(r0, Operand::Zero()); |
4649 Split(cond, if_true, if_false, fall_through); | 4632 Split(cond, if_true, if_false, fall_through); |
4650 } | 4633 } |
4651 } | 4634 } |
4652 | 4635 |
4653 // Convert the result of the comparison into one expected for this | 4636 // Convert the result of the comparison into one expected for this |
4654 // expression's context. | 4637 // expression's context. |
4655 context()->Plug(if_true, if_false); | 4638 context()->Plug(if_true, if_false); |
(...skipping 14 matching lines...) Expand all Loading... |
4670 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4653 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
4671 if (expr->op() == Token::EQ_STRICT) { | 4654 if (expr->op() == Token::EQ_STRICT) { |
4672 Heap::RootListIndex nil_value = nil == kNullValue ? | 4655 Heap::RootListIndex nil_value = nil == kNullValue ? |
4673 Heap::kNullValueRootIndex : | 4656 Heap::kNullValueRootIndex : |
4674 Heap::kUndefinedValueRootIndex; | 4657 Heap::kUndefinedValueRootIndex; |
4675 __ LoadRoot(r1, nil_value); | 4658 __ LoadRoot(r1, nil_value); |
4676 __ cmp(r0, r1); | 4659 __ cmp(r0, r1); |
4677 Split(eq, if_true, if_false, fall_through); | 4660 Split(eq, if_true, if_false, fall_through); |
4678 } else { | 4661 } else { |
4679 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); | 4662 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); |
4680 CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); | 4663 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId()); |
4681 __ cmp(r0, Operand(0)); | 4664 __ cmp(r0, Operand(0)); |
4682 Split(ne, if_true, if_false, fall_through); | 4665 Split(ne, if_true, if_false, fall_through); |
4683 } | 4666 } |
4684 context()->Plug(if_true, if_false); | 4667 context()->Plug(if_true, if_false); |
4685 } | 4668 } |
4686 | 4669 |
4687 | 4670 |
4688 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { | 4671 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { |
4689 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 4672 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
4690 context()->Plug(r0); | 4673 context()->Plug(r0); |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4913 ASSERT(Memory::uint32_at(interrupt_address_pointer) == | 4896 ASSERT(Memory::uint32_at(interrupt_address_pointer) == |
4914 reinterpret_cast<uint32_t>( | 4897 reinterpret_cast<uint32_t>( |
4915 isolate->builtins()->OsrAfterStackCheck()->entry())); | 4898 isolate->builtins()->OsrAfterStackCheck()->entry())); |
4916 return OSR_AFTER_STACK_CHECK; | 4899 return OSR_AFTER_STACK_CHECK; |
4917 } | 4900 } |
4918 | 4901 |
4919 | 4902 |
4920 } } // namespace v8::internal | 4903 } } // namespace v8::internal |
4921 | 4904 |
4922 #endif // V8_TARGET_ARCH_ARM | 4905 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |