Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(162)

Side by Side Diff: src/arm/codegen-arm.cc

Issue 3125011: ARM: Ensure that we are not in a spilled scope when calling... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 501 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 ToBoolean(true_target, false_target); 512 ToBoolean(true_target, false_target);
513 } 513 }
514 ASSERT(!force_cc || !has_valid_frame() || has_cc()); 514 ASSERT(!force_cc || !has_valid_frame() || has_cc());
515 ASSERT(!has_valid_frame() || 515 ASSERT(!has_valid_frame() ||
516 (has_cc() && frame_->height() == original_height) || 516 (has_cc() && frame_->height() == original_height) ||
517 (!has_cc() && frame_->height() == original_height + 1)); 517 (!has_cc() && frame_->height() == original_height + 1));
518 } 518 }
519 519
520 520
521 void CodeGenerator::Load(Expression* expr) { 521 void CodeGenerator::Load(Expression* expr) {
522 frame_->AssertIsNotSpilled();
522 #ifdef DEBUG 523 #ifdef DEBUG
523 int original_height = frame_->height(); 524 int original_height = frame_->height();
524 #endif 525 #endif
525 JumpTarget true_target; 526 JumpTarget true_target;
526 JumpTarget false_target; 527 JumpTarget false_target;
527 LoadCondition(expr, &true_target, &false_target, false); 528 LoadCondition(expr, &true_target, &false_target, false);
528 529
529 if (has_cc()) { 530 if (has_cc()) {
530 // Convert cc_reg_ into a boolean value. 531 // Convert cc_reg_ into a boolean value.
531 JumpTarget loaded; 532 JumpTarget loaded;
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 } 669 }
669 670
670 671
671 Reference::Reference(CodeGenerator* cgen, 672 Reference::Reference(CodeGenerator* cgen,
672 Expression* expression, 673 Expression* expression,
673 bool persist_after_get) 674 bool persist_after_get)
674 : cgen_(cgen), 675 : cgen_(cgen),
675 expression_(expression), 676 expression_(expression),
676 type_(ILLEGAL), 677 type_(ILLEGAL),
677 persist_after_get_(persist_after_get) { 678 persist_after_get_(persist_after_get) {
679 cgen->frame()->AssertIsNotSpilled();
678 cgen->LoadReference(this); 680 cgen->LoadReference(this);
679 } 681 }
680 682
681 683
682 Reference::~Reference() { 684 Reference::~Reference() {
683 ASSERT(is_unloaded() || is_illegal()); 685 ASSERT(is_unloaded() || is_illegal());
684 } 686 }
685 687
686 688
687 void CodeGenerator::LoadReference(Reference* ref) { 689 void CodeGenerator::LoadReference(Reference* ref) {
(...skipping 1190 matching lines...) Expand 10 before | Expand all | Expand 10 after
1878 1880
1879 1881
1880 void CodeGenerator::VisitBreakStatement(BreakStatement* node) { 1882 void CodeGenerator::VisitBreakStatement(BreakStatement* node) {
1881 Comment cmnt(masm_, "[ BreakStatement"); 1883 Comment cmnt(masm_, "[ BreakStatement");
1882 CodeForStatementPosition(node); 1884 CodeForStatementPosition(node);
1883 node->target()->break_target()->Jump(); 1885 node->target()->break_target()->Jump();
1884 } 1886 }
1885 1887
1886 1888
1887 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) { 1889 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) {
1888 frame_->SpillAll();
1889 Comment cmnt(masm_, "[ ReturnStatement"); 1890 Comment cmnt(masm_, "[ ReturnStatement");
1890 1891
1891 CodeForStatementPosition(node); 1892 CodeForStatementPosition(node);
1892 Load(node->expression()); 1893 Load(node->expression());
1894 frame_->PopToR0();
1895 frame_->PrepareForReturn();
1893 if (function_return_is_shadowed_) { 1896 if (function_return_is_shadowed_) {
1894 frame_->EmitPop(r0);
1895 function_return_.Jump(); 1897 function_return_.Jump();
1896 } else { 1898 } else {
1897 // Pop the result from the frame and prepare the frame for 1899 // Pop the result from the frame and prepare the frame for
1898 // returning thus making it easier to merge. 1900 // returning thus making it easier to merge.
1899 frame_->PopToR0();
1900 frame_->PrepareForReturn();
1901 if (function_return_.is_bound()) { 1901 if (function_return_.is_bound()) {
1902 // If the function return label is already bound we reuse the 1902 // If the function return label is already bound we reuse the
1903 // code by jumping to the return site. 1903 // code by jumping to the return site.
1904 function_return_.Jump(); 1904 function_return_.Jump();
1905 } else { 1905 } else {
1906 function_return_.Bind(); 1906 function_return_.Bind();
1907 GenerateReturnSequence(); 1907 GenerateReturnSequence();
1908 } 1908 }
1909 } 1909 }
1910 } 1910 }
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
2286 } 2286 }
2287 DecrementLoopNesting(); 2287 DecrementLoopNesting();
2288 ASSERT(!has_valid_frame() || frame_->height() == original_height); 2288 ASSERT(!has_valid_frame() || frame_->height() == original_height);
2289 } 2289 }
2290 2290
2291 2291
2292 void CodeGenerator::VisitForInStatement(ForInStatement* node) { 2292 void CodeGenerator::VisitForInStatement(ForInStatement* node) {
2293 #ifdef DEBUG 2293 #ifdef DEBUG
2294 int original_height = frame_->height(); 2294 int original_height = frame_->height();
2295 #endif 2295 #endif
2296 VirtualFrame::SpilledScope spilled_scope(frame_);
2297 Comment cmnt(masm_, "[ ForInStatement"); 2296 Comment cmnt(masm_, "[ ForInStatement");
2298 CodeForStatementPosition(node); 2297 CodeForStatementPosition(node);
2299 2298
2300 JumpTarget primitive; 2299 JumpTarget primitive;
2301 JumpTarget jsobject; 2300 JumpTarget jsobject;
2302 JumpTarget fixed_array; 2301 JumpTarget fixed_array;
2303 JumpTarget entry(JumpTarget::BIDIRECTIONAL); 2302 JumpTarget entry(JumpTarget::BIDIRECTIONAL);
2304 JumpTarget end_del_check; 2303 JumpTarget end_del_check;
2305 JumpTarget exit; 2304 JumpTarget exit;
2306 2305
2307 // Get the object to enumerate over (converted to JSObject). 2306 // Get the object to enumerate over (converted to JSObject).
2308 Load(node->enumerable()); 2307 Load(node->enumerable());
2309 2308
2309 VirtualFrame::SpilledScope spilled_scope(frame_);
2310 // Both SpiderMonkey and kjs ignore null and undefined in contrast 2310 // Both SpiderMonkey and kjs ignore null and undefined in contrast
2311 // to the specification. 12.6.4 mandates a call to ToObject. 2311 // to the specification. 12.6.4 mandates a call to ToObject.
2312 frame_->EmitPop(r0); 2312 frame_->EmitPop(r0);
2313 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 2313 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
2314 __ cmp(r0, ip); 2314 __ cmp(r0, ip);
2315 exit.Branch(eq); 2315 exit.Branch(eq);
2316 __ LoadRoot(ip, Heap::kNullValueRootIndex); 2316 __ LoadRoot(ip, Heap::kNullValueRootIndex);
2317 __ cmp(r0, ip); 2317 __ cmp(r0, ip);
2318 exit.Branch(eq); 2318 exit.Branch(eq);
2319 2319
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
2469 frame_->EmitPush(r3); // push entry 2469 frame_->EmitPush(r3); // push entry
2470 frame_->InvokeBuiltin(Builtins::FILTER_KEY, CALL_JS, 2); 2470 frame_->InvokeBuiltin(Builtins::FILTER_KEY, CALL_JS, 2);
2471 __ mov(r3, Operand(r0), SetCC); 2471 __ mov(r3, Operand(r0), SetCC);
2472 // If the property has been removed while iterating, we just skip it. 2472 // If the property has been removed while iterating, we just skip it.
2473 node->continue_target()->Branch(eq); 2473 node->continue_target()->Branch(eq);
2474 2474
2475 end_del_check.Bind(); 2475 end_del_check.Bind();
2476 // Store the entry in the 'each' expression and take another spin in the 2476 // Store the entry in the 'each' expression and take another spin in the
2477 // loop. r3: i'th entry of the enum cache (or string there of) 2477 // loop. r3: i'th entry of the enum cache (or string there of)
2478 frame_->EmitPush(r3); // push entry 2478 frame_->EmitPush(r3); // push entry
2479 { Reference each(this, node->each()); 2479 { VirtualFrame::RegisterAllocationScope scope(this);
2480 Reference each(this, node->each());
2480 if (!each.is_illegal()) { 2481 if (!each.is_illegal()) {
2481 if (each.size() > 0) { 2482 if (each.size() > 0) {
2483 // Loading a reference may leave the frame in an unspilled state.
2484 frame_->SpillAll(); // Sync stack to memory.
2485 // Get the value (under the reference on the stack) from memory.
2482 __ ldr(r0, frame_->ElementAt(each.size())); 2486 __ ldr(r0, frame_->ElementAt(each.size()));
2483 frame_->EmitPush(r0); 2487 frame_->EmitPush(r0);
2484 each.SetValue(NOT_CONST_INIT, UNLIKELY_SMI); 2488 each.SetValue(NOT_CONST_INIT, UNLIKELY_SMI);
2485 frame_->Drop(2); 2489 frame_->Drop(2); // The result of the set and the extra pushed value.
2486 } else { 2490 } else {
2487 // If the reference was to a slot we rely on the convenient property 2491 // If the reference was to a slot we rely on the convenient property
2488 // that it doesn't matter whether a value (eg, r3 pushed above) is 2492 // that it doesn't matter whether a value (eg, ebx pushed above) is
2489 // right on top of or right underneath a zero-sized reference. 2493 // right on top of or right underneath a zero-sized reference.
2490 each.SetValue(NOT_CONST_INIT, UNLIKELY_SMI); 2494 each.SetValue(NOT_CONST_INIT, UNLIKELY_SMI);
2491 frame_->Drop(); 2495 frame_->Drop(1); // Drop the result of the set operation.
2492 } 2496 }
2493 } 2497 }
2494 } 2498 }
2495 // Body. 2499 // Body.
2496 CheckStack(); // TODO(1222600): ignore if body contains calls. 2500 CheckStack(); // TODO(1222600): ignore if body contains calls.
2497 Visit(node->body()); 2501 { VirtualFrame::RegisterAllocationScope scope(this);
2502 Visit(node->body());
2503 }
2498 2504
2499 // Next. Reestablish a spilled frame in case we are coming here via 2505 // Next. Reestablish a spilled frame in case we are coming here via
2500 // a continue in the body. 2506 // a continue in the body.
2501 node->continue_target()->Bind(); 2507 node->continue_target()->Bind();
2502 frame_->SpillAll(); 2508 frame_->SpillAll();
2503 frame_->EmitPop(r0); 2509 frame_->EmitPop(r0);
2504 __ add(r0, r0, Operand(Smi::FromInt(1))); 2510 __ add(r0, r0, Operand(Smi::FromInt(1)));
2505 frame_->EmitPush(r0); 2511 frame_->EmitPush(r0);
2506 entry.Jump(); 2512 entry.Jump();
2507 2513
(...skipping 26 matching lines...) Expand all
2534 frame_->EmitPush(r0); 2540 frame_->EmitPush(r0);
2535 2541
2536 // Store the caught exception in the catch variable. 2542 // Store the caught exception in the catch variable.
2537 Variable* catch_var = node->catch_var()->var(); 2543 Variable* catch_var = node->catch_var()->var();
2538 ASSERT(catch_var != NULL && catch_var->slot() != NULL); 2544 ASSERT(catch_var != NULL && catch_var->slot() != NULL);
2539 StoreToSlot(catch_var->slot(), NOT_CONST_INIT); 2545 StoreToSlot(catch_var->slot(), NOT_CONST_INIT);
2540 2546
2541 // Remove the exception from the stack. 2547 // Remove the exception from the stack.
2542 frame_->Drop(); 2548 frame_->Drop();
2543 2549
2544 VisitStatements(node->catch_block()->statements()); 2550 { VirtualFrame::RegisterAllocationScope scope(this);
2551 VisitStatements(node->catch_block()->statements());
2552 }
2545 if (frame_ != NULL) { 2553 if (frame_ != NULL) {
2546 exit.Jump(); 2554 exit.Jump();
2547 } 2555 }
2548 2556
2549 2557
2550 // --- Try block --- 2558 // --- Try block ---
2551 try_block.Bind(); 2559 try_block.Bind();
2552 2560
2553 frame_->PushTryHandler(TRY_CATCH_HANDLER); 2561 frame_->PushTryHandler(TRY_CATCH_HANDLER);
2554 int handler_height = frame_->height(); 2562 int handler_height = frame_->height();
(...skipping 14 matching lines...) Expand all
2569 bool function_return_was_shadowed = function_return_is_shadowed_; 2577 bool function_return_was_shadowed = function_return_is_shadowed_;
2570 function_return_is_shadowed_ = true; 2578 function_return_is_shadowed_ = true;
2571 ASSERT(shadows[kReturnShadowIndex]->other_target() == &function_return_); 2579 ASSERT(shadows[kReturnShadowIndex]->other_target() == &function_return_);
2572 2580
2573 // Add the remaining shadow targets. 2581 // Add the remaining shadow targets.
2574 for (int i = 0; i < nof_escapes; i++) { 2582 for (int i = 0; i < nof_escapes; i++) {
2575 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); 2583 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i)));
2576 } 2584 }
2577 2585
2578 // Generate code for the statements in the try block. 2586 // Generate code for the statements in the try block.
2579 VisitStatements(node->try_block()->statements()); 2587 { VirtualFrame::RegisterAllocationScope scope(this);
2588 VisitStatements(node->try_block()->statements());
2589 }
2580 2590
2581 // Stop the introduced shadowing and count the number of required unlinks. 2591 // Stop the introduced shadowing and count the number of required unlinks.
2582 // After shadowing stops, the original labels are unshadowed and the 2592 // After shadowing stops, the original labels are unshadowed and the
2583 // LabelShadows represent the formerly shadowing labels. 2593 // LabelShadows represent the formerly shadowing labels.
2584 bool has_unlinks = false; 2594 bool has_unlinks = false;
2585 for (int i = 0; i < shadows.length(); i++) { 2595 for (int i = 0; i < shadows.length(); i++) {
2586 shadows[i]->StopShadowing(); 2596 shadows[i]->StopShadowing();
2587 has_unlinks = has_unlinks || shadows[i]->is_linked(); 2597 has_unlinks = has_unlinks || shadows[i]->is_linked();
2588 } 2598 }
2589 function_return_is_shadowed_ = function_return_was_shadowed; 2599 function_return_is_shadowed_ = function_return_was_shadowed;
2590 2600
2591 // Get an external reference to the handler address. 2601 // Get an external reference to the handler address.
2592 ExternalReference handler_address(Top::k_handler_address); 2602 ExternalReference handler_address(Top::k_handler_address);
2593 2603
2594 // If we can fall off the end of the try block, unlink from try chain. 2604 // If we can fall off the end of the try block, unlink from try chain.
2595 if (has_valid_frame()) { 2605 if (has_valid_frame()) {
2596 // The next handler address is on top of the frame. Unlink from 2606 // The next handler address is on top of the frame. Unlink from
2597 // the handler list and drop the rest of this handler from the 2607 // the handler list and drop the rest of this handler from the
2598 // frame. 2608 // frame.
2599 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 2609 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
Søren Thygesen Gjesse 2010/08/16 07:15:36 Maybe add the r0 comment here as well.
2600 frame_->EmitPop(r1); 2610 frame_->EmitPop(r1);
2601 __ mov(r3, Operand(handler_address)); 2611 __ mov(r3, Operand(handler_address));
2602 __ str(r1, MemOperand(r3)); 2612 __ str(r1, MemOperand(r3));
2603 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); 2613 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
2604 if (has_unlinks) { 2614 if (has_unlinks) {
2605 exit.Jump(); 2615 exit.Jump();
2606 } 2616 }
2607 } 2617 }
2608 2618
2609 // Generate unlink code for the (formerly) shadowing labels that have been 2619 // Generate unlink code for the (formerly) shadowing labels that have been
2610 // jumped to. Deallocate each shadow target. 2620 // jumped to. Deallocate each shadow target.
2611 for (int i = 0; i < shadows.length(); i++) { 2621 for (int i = 0; i < shadows.length(); i++) {
2612 if (shadows[i]->is_linked()) { 2622 if (shadows[i]->is_linked()) {
2613 // Unlink from try chain; 2623 // Unlink from try chain;
2614 shadows[i]->Bind(); 2624 shadows[i]->Bind();
2615 // Because we can be jumping here (to spilled code) from unspilled 2625 // Because we can be jumping here (to spilled code) from unspilled
2616 // code, we need to reestablish a spilled frame at this block. 2626 // code, we need to reestablish a spilled frame at this block.
2617 frame_->SpillAll(); 2627 frame_->SpillAll();
2618 2628
2619 // Reload sp from the top handler, because some statements that we 2629 // Reload sp from the top handler, because some statements that we
2620 // break from (eg, for...in) may have left stuff on the stack. 2630 // break from (eg, for...in) may have left stuff on the stack.
2621 __ mov(r3, Operand(handler_address)); 2631 __ mov(r3, Operand(handler_address));
2622 __ ldr(sp, MemOperand(r3)); 2632 __ ldr(sp, MemOperand(r3));
2623 frame_->Forget(frame_->height() - handler_height); 2633 frame_->Forget(frame_->height() - handler_height);
2624 2634
2625 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 2635 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
2626 frame_->EmitPop(r1); 2636 frame_->EmitPop(r1); // r0 can contain the return value.
2627 __ str(r1, MemOperand(r3)); 2637 __ str(r1, MemOperand(r3));
2628 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); 2638 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
2629 2639
2630 if (!function_return_is_shadowed_ && i == kReturnShadowIndex) { 2640 if (!function_return_is_shadowed_ && i == kReturnShadowIndex) {
2631 frame_->PrepareForReturn(); 2641 frame_->PrepareForReturn();
2632 } 2642 }
2633 shadows[i]->other_target()->Jump(); 2643 shadows[i]->other_target()->Jump();
2634 } 2644 }
2635 } 2645 }
2636 2646
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2683 bool function_return_was_shadowed = function_return_is_shadowed_; 2693 bool function_return_was_shadowed = function_return_is_shadowed_;
2684 function_return_is_shadowed_ = true; 2694 function_return_is_shadowed_ = true;
2685 ASSERT(shadows[kReturnShadowIndex]->other_target() == &function_return_); 2695 ASSERT(shadows[kReturnShadowIndex]->other_target() == &function_return_);
2686 2696
2687 // Add the remaining shadow targets. 2697 // Add the remaining shadow targets.
2688 for (int i = 0; i < nof_escapes; i++) { 2698 for (int i = 0; i < nof_escapes; i++) {
2689 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); 2699 shadows.Add(new ShadowTarget(node->escaping_targets()->at(i)));
2690 } 2700 }
2691 2701
2692 // Generate code for the statements in the try block. 2702 // Generate code for the statements in the try block.
2693 VisitStatements(node->try_block()->statements()); 2703 { VirtualFrame::RegisterAllocationScope scope(this);
2704 VisitStatements(node->try_block()->statements());
2705 }
2694 2706
2695 // Stop the introduced shadowing and count the number of required unlinks. 2707 // Stop the introduced shadowing and count the number of required unlinks.
2696 // After shadowing stops, the original labels are unshadowed and the 2708 // After shadowing stops, the original labels are unshadowed and the
2697 // LabelShadows represent the formerly shadowing labels. 2709 // LabelShadows represent the formerly shadowing labels.
2698 int nof_unlinks = 0; 2710 int nof_unlinks = 0;
2699 for (int i = 0; i < shadows.length(); i++) { 2711 for (int i = 0; i < shadows.length(); i++) {
2700 shadows[i]->StopShadowing(); 2712 shadows[i]->StopShadowing();
2701 if (shadows[i]->is_linked()) nof_unlinks++; 2713 if (shadows[i]->is_linked()) nof_unlinks++;
2702 } 2714 }
2703 function_return_is_shadowed_ = function_return_was_shadowed; 2715 function_return_is_shadowed_ = function_return_was_shadowed;
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2773 // --- Finally block --- 2785 // --- Finally block ---
2774 finally_block.Bind(); 2786 finally_block.Bind();
2775 2787
2776 // Push the state on the stack. 2788 // Push the state on the stack.
2777 frame_->EmitPush(r2); 2789 frame_->EmitPush(r2);
2778 2790
2779 // We keep two elements on the stack - the (possibly faked) result 2791 // We keep two elements on the stack - the (possibly faked) result
2780 // and the state - while evaluating the finally block. 2792 // and the state - while evaluating the finally block.
2781 // 2793 //
2782 // Generate code for the statements in the finally block. 2794 // Generate code for the statements in the finally block.
2783 VisitStatements(node->finally_block()->statements()); 2795 { VirtualFrame::RegisterAllocationScope scope(this);
2796 VisitStatements(node->finally_block()->statements());
2797 }
2784 2798
2785 if (has_valid_frame()) { 2799 if (has_valid_frame()) {
2786 // Restore state and return value or faked TOS. 2800 // Restore state and return value or faked TOS.
2787 frame_->EmitPop(r2); 2801 frame_->EmitPop(r2);
2788 frame_->EmitPop(r0); 2802 frame_->EmitPop(r0);
2789 } 2803 }
2790 2804
2791 // Generate code to jump to the right destination for all used 2805 // Generate code to jump to the right destination for all used
2792 // formerly shadowing targets. Deallocate each shadow target. 2806 // formerly shadowing targets. Deallocate each shadow target.
2793 for (int i = 0; i < shadows.length(); i++) { 2807 for (int i = 0; i < shadows.length(); i++) {
(...skipping 1159 matching lines...) Expand 10 before | Expand all | Expand 10 after
3953 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP; 3967 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
3954 Handle<Code> stub = ComputeCallInitialize(arg_count, in_loop); 3968 Handle<Code> stub = ComputeCallInitialize(arg_count, in_loop);
3955 CodeForSourcePosition(node->position()); 3969 CodeForSourcePosition(node->position());
3956 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET_CONTEXT, 3970 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET_CONTEXT,
3957 arg_count + 1); 3971 arg_count + 1);
3958 __ ldr(cp, frame_->Context()); 3972 __ ldr(cp, frame_->Context());
3959 frame_->EmitPush(r0); 3973 frame_->EmitPush(r0);
3960 3974
3961 } else if (var != NULL && var->slot() != NULL && 3975 } else if (var != NULL && var->slot() != NULL &&
3962 var->slot()->type() == Slot::LOOKUP) { 3976 var->slot()->type() == Slot::LOOKUP) {
3963 VirtualFrame::SpilledScope spilled_scope(frame_);
3964 // ---------------------------------- 3977 // ----------------------------------
3965 // JavaScript examples: 3978 // JavaScript examples:
3966 // 3979 //
3967 // with (obj) foo(1, 2, 3) // foo may be in obj. 3980 // with (obj) foo(1, 2, 3) // foo may be in obj.
3968 // 3981 //
3969 // function f() {}; 3982 // function f() {};
3970 // function g() { 3983 // function g() {
3971 // eval(...); 3984 // eval(...);
3972 // f(); // f could be in extension object. 3985 // f(); // f could be in extension object.
3973 // } 3986 // }
3974 // ---------------------------------- 3987 // ----------------------------------
3975 3988
3976 // JumpTargets do not yet support merging frames so the frame must be
3977 // spilled when jumping to these targets.
3978 JumpTarget slow, done; 3989 JumpTarget slow, done;
3979 3990
3980 // Generate fast case for loading functions from slots that 3991 // Generate fast case for loading functions from slots that
3981 // correspond to local/global variables or arguments unless they 3992 // correspond to local/global variables or arguments unless they
3982 // are shadowed by eval-introduced bindings. 3993 // are shadowed by eval-introduced bindings.
3983 EmitDynamicLoadFromSlotFastCase(var->slot(), 3994 EmitDynamicLoadFromSlotFastCase(var->slot(),
3984 NOT_INSIDE_TYPEOF, 3995 NOT_INSIDE_TYPEOF,
3985 &slow, 3996 &slow,
3986 &done); 3997 &done);
3987 3998
3988 slow.Bind(); 3999 slow.Bind();
3989 // Load the function 4000 // Load the function
3990 frame_->EmitPush(cp); 4001 frame_->EmitPush(cp);
3991 __ mov(r0, Operand(var->name())); 4002 frame_->EmitPush(Operand(var->name()));
3992 frame_->EmitPush(r0);
3993 frame_->CallRuntime(Runtime::kLoadContextSlot, 2); 4003 frame_->CallRuntime(Runtime::kLoadContextSlot, 2);
3994 // r0: slot value; r1: receiver 4004 // r0: slot value; r1: receiver
3995 4005
3996 // Load the receiver. 4006 // Load the receiver.
3997 frame_->EmitPush(r0); // function 4007 frame_->EmitPush(r0); // function
3998 frame_->EmitPush(r1); // receiver 4008 frame_->EmitPush(r1); // receiver
3999 4009
4000 // If fast case code has been generated, emit code to push the 4010 // If fast case code has been generated, emit code to push the
4001 // function and receiver and have the slow path jump around this 4011 // function and receiver and have the slow path jump around this
4002 // code. 4012 // code.
4003 if (done.is_linked()) { 4013 if (done.is_linked()) {
4004 JumpTarget call; 4014 JumpTarget call;
4005 call.Jump(); 4015 call.Jump();
4006 done.Bind(); 4016 done.Bind();
4007 frame_->EmitPush(r0); // function 4017 frame_->EmitPush(r0); // function
4008 LoadGlobalReceiver(r1); // receiver 4018 LoadGlobalReceiver(VirtualFrame::scratch0()); // receiver
4009 call.Bind(); 4019 call.Bind();
4010 } 4020 }
4011 4021
4012 // Call the function. At this point, everything is spilled but the 4022 // Call the function. At this point, everything is spilled but the
4013 // function and receiver are in r0 and r1. 4023 // function and receiver are in r0 and r1.
4014 CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position()); 4024 CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position());
4015 frame_->EmitPush(r0); 4025 frame_->EmitPush(r0);
4016 4026
4017 } else if (property != NULL) { 4027 } else if (property != NULL) {
4018 // Check if the key is a literal string. 4028 // Check if the key is a literal string.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
4053 CodeForSourcePosition(node->position()); 4063 CodeForSourcePosition(node->position());
4054 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET, arg_count + 1); 4064 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET, arg_count + 1);
4055 __ ldr(cp, frame_->Context()); 4065 __ ldr(cp, frame_->Context());
4056 frame_->EmitPush(r0); 4066 frame_->EmitPush(r0);
4057 } 4067 }
4058 4068
4059 } else { 4069 } else {
4060 // ------------------------------------------- 4070 // -------------------------------------------
4061 // JavaScript example: 'array[index](1, 2, 3)' 4071 // JavaScript example: 'array[index](1, 2, 3)'
4062 // ------------------------------------------- 4072 // -------------------------------------------
4063 VirtualFrame::SpilledScope spilled_scope(frame_);
4064
4065 Load(property->obj()); 4073 Load(property->obj());
4066 if (property->is_synthetic()) { 4074 if (property->is_synthetic()) {
4067 Load(property->key()); 4075 Load(property->key());
4068 EmitKeyedLoad(); 4076 EmitKeyedLoad();
4069 // Put the function below the receiver. 4077 // Put the function below the receiver.
4070 // Use the global receiver. 4078 // Use the global receiver.
4071 frame_->EmitPush(r0); // Function. 4079 frame_->EmitPush(r0); // Function.
4072 LoadGlobalReceiver(r0); 4080 LoadGlobalReceiver(VirtualFrame::scratch0());
4073 // Call the function. 4081 // Call the function.
4074 CallWithArguments(args, RECEIVER_MIGHT_BE_VALUE, node->position()); 4082 CallWithArguments(args, RECEIVER_MIGHT_BE_VALUE, node->position());
4075 frame_->EmitPush(r0); 4083 frame_->EmitPush(r0);
4076 } else { 4084 } else {
4077 // Load the arguments. 4085 // Load the arguments.
4078 int arg_count = args->length(); 4086 int arg_count = args->length();
4079 for (int i = 0; i < arg_count; i++) { 4087 for (int i = 0; i < arg_count; i++) {
4080 Load(args->at(i)); 4088 Load(args->at(i));
4081 } 4089 }
4082 4090
4083 // Set the name register and call the IC initialization code. 4091 // Set the name register and call the IC initialization code.
4084 Load(property->key()); 4092 Load(property->key());
4093 frame_->SpillAll();
4085 frame_->EmitPop(r2); // Function name. 4094 frame_->EmitPop(r2); // Function name.
4086 4095
4087 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP; 4096 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
4088 Handle<Code> stub = ComputeKeyedCallInitialize(arg_count, in_loop); 4097 Handle<Code> stub = ComputeKeyedCallInitialize(arg_count, in_loop);
4089 CodeForSourcePosition(node->position()); 4098 CodeForSourcePosition(node->position());
4090 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET, arg_count + 1); 4099 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET, arg_count + 1);
4091 __ ldr(cp, frame_->Context()); 4100 __ ldr(cp, frame_->Context());
4092 frame_->EmitPush(r0); 4101 frame_->EmitPush(r0);
4093 } 4102 }
4094 } 4103 }
4095 4104
4096 } else { 4105 } else {
4097 // ---------------------------------- 4106 // ----------------------------------
4098 // JavaScript example: 'foo(1, 2, 3)' // foo is not global 4107 // JavaScript example: 'foo(1, 2, 3)' // foo is not global
4099 // ---------------------------------- 4108 // ----------------------------------
4100 4109
4101 // Load the function. 4110 // Load the function.
4102 Load(function); 4111 Load(function);
4103 4112
4104 VirtualFrame::SpilledScope spilled_scope(frame_);
4105
4106 // Pass the global proxy as the receiver. 4113 // Pass the global proxy as the receiver.
4107 LoadGlobalReceiver(r0); 4114 LoadGlobalReceiver(VirtualFrame::scratch0());
4108 4115
4109 // Call the function. 4116 // Call the function.
4110 CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position()); 4117 CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position());
4111 frame_->EmitPush(r0); 4118 frame_->EmitPush(r0);
4112 } 4119 }
4113 ASSERT_EQ(original_height + 1, frame_->height()); 4120 ASSERT_EQ(original_height + 1, frame_->height());
4114 } 4121 }
4115 4122
4116 4123
4117 void CodeGenerator::VisitCallNew(CallNew* node) { 4124 void CodeGenerator::VisitCallNew(CallNew* node) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
4152 Handle<Code> ic(Builtins::builtin(Builtins::JSConstructCall)); 4159 Handle<Code> ic(Builtins::builtin(Builtins::JSConstructCall));
4153 frame_->CallCodeObject(ic, RelocInfo::CONSTRUCT_CALL, arg_count + 1); 4160 frame_->CallCodeObject(ic, RelocInfo::CONSTRUCT_CALL, arg_count + 1);
4154 4161
4155 // Discard old TOS value and push r0 on the stack (same as Pop(), push(r0)). 4162 // Discard old TOS value and push r0 on the stack (same as Pop(), push(r0)).
4156 __ str(r0, frame_->Top()); 4163 __ str(r0, frame_->Top());
4157 ASSERT_EQ(original_height + 1, frame_->height()); 4164 ASSERT_EQ(original_height + 1, frame_->height());
4158 } 4165 }
4159 4166
4160 4167
4161 void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) { 4168 void CodeGenerator::GenerateClassOf(ZoneList<Expression*>* args) {
4162 JumpTarget leave, null, function, non_function_constructor;
4163 Register scratch = VirtualFrame::scratch0(); 4169 Register scratch = VirtualFrame::scratch0();
4170 JumpTarget null, function, leave, non_function_constructor;
4164 4171
4165 // Load the object into register. 4172 // Load the object into register.
4166 ASSERT(args->length() == 1); 4173 ASSERT(args->length() == 1);
4167 Load(args->at(0)); 4174 Load(args->at(0));
4168 Register tos = frame_->PopToRegister(); 4175 Register tos = frame_->PopToRegister();
4169 4176
4170 // If the object is a smi, we return null. 4177 // If the object is a smi, we return null.
4171 __ tst(tos, Operand(kSmiTagMask)); 4178 __ tst(tos, Operand(kSmiTagMask));
4172 null.Branch(eq); 4179 null.Branch(eq);
4173 4180
(...skipping 7392 matching lines...) Expand 10 before | Expand all | Expand 10 after
11566 __ bind(&string_add_runtime); 11573 __ bind(&string_add_runtime);
11567 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); 11574 __ TailCallRuntime(Runtime::kStringAdd, 2, 1);
11568 } 11575 }
11569 11576
11570 11577
11571 #undef __ 11578 #undef __
11572 11579
11573 } } // namespace v8::internal 11580 } } // namespace v8::internal
11574 11581
11575 #endif // V8_TARGET_ARCH_ARM 11582 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698