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

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

Issue 507036: Use one runtime call for creating object/array literals in... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years 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 | src/arm/fast-codegen-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 2583 matching lines...) Expand 10 before | Expand all | Expand 10 after
2594 frame_->CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); 2594 frame_->CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
2595 __ mov(r2, Operand(r0)); 2595 __ mov(r2, Operand(r0));
2596 2596
2597 done.Bind(); 2597 done.Bind();
2598 // Push the literal. 2598 // Push the literal.
2599 frame_->EmitPush(r2); 2599 frame_->EmitPush(r2);
2600 ASSERT(frame_->height() == original_height + 1); 2600 ASSERT(frame_->height() == original_height + 1);
2601 } 2601 }
2602 2602
2603 2603
2604 // This deferred code stub will be used for creating the boilerplate
2605 // by calling Runtime_CreateObjectLiteralBoilerplate.
2606 // Each created boilerplate is stored in the JSFunction and they are
2607 // therefore context dependent.
2608 class DeferredObjectLiteral: public DeferredCode {
2609 public:
2610 explicit DeferredObjectLiteral(ObjectLiteral* node) : node_(node) {
2611 set_comment("[ DeferredObjectLiteral");
2612 }
2613
2614 virtual void Generate();
2615
2616 private:
2617 ObjectLiteral* node_;
2618 };
2619
2620
2621 void DeferredObjectLiteral::Generate() {
2622 // Argument is passed in r1.
2623
2624 // If the entry is undefined we call the runtime system to compute
2625 // the literal.
2626 // Literal array (0).
2627 __ push(r1);
2628 // Literal index (1).
2629 __ mov(r0, Operand(Smi::FromInt(node_->literal_index())));
2630 __ push(r0);
2631 // Constant properties (2).
2632 __ mov(r0, Operand(node_->constant_properties()));
2633 __ push(r0);
2634 __ CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3);
2635 __ mov(r2, Operand(r0));
2636 // Result is returned in r2.
2637 }
2638
2639
2640 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { 2604 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) {
2641 #ifdef DEBUG 2605 #ifdef DEBUG
2642 int original_height = frame_->height(); 2606 int original_height = frame_->height();
2643 #endif 2607 #endif
2644 VirtualFrame::SpilledScope spilled_scope; 2608 VirtualFrame::SpilledScope spilled_scope;
2645 Comment cmnt(masm_, "[ ObjectLiteral"); 2609 Comment cmnt(masm_, "[ ObjectLiteral");
2646 2610
2647 DeferredObjectLiteral* deferred = new DeferredObjectLiteral(node);
2648
2649 // Retrieve the literal array and check the allocated entry.
2650
2651 // Load the function of this activation. 2611 // Load the function of this activation.
2652 __ ldr(r1, frame_->Function()); 2612 __ ldr(r2, frame_->Function());
2653 2613 // Literal array.
2654 // Load the literals array of the function. 2614 __ ldr(r2, FieldMemOperand(r2, JSFunction::kLiteralsOffset));
2655 __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset)); 2615 // Literal index.
2656 2616 __ mov(r1, Operand(Smi::FromInt(node->literal_index())));
2657 // Load the literal at the ast saved index. 2617 // Constant properties.
2658 int literal_offset = 2618 __ mov(r0, Operand(node->constant_properties()));
2659 FixedArray::kHeaderSize + node->literal_index() * kPointerSize; 2619 frame_->EmitPushMultiple(3, r2.bit() | r1.bit() | r0.bit());
2660 __ ldr(r2, FieldMemOperand(r1, literal_offset)); 2620 if (node->depth() > 1) {
2661 2621 frame_->CallRuntime(Runtime::kCreateObjectLiteral, 3);
2662 // Check whether we need to materialize the object literal boilerplate. 2622 } else {
2663 // If so, jump to the deferred code. 2623 frame_->CallRuntime(Runtime::kCreateObjectLiteralShallow, 3);
2664 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
2665 __ cmp(r2, Operand(ip));
2666 deferred->Branch(eq);
2667 deferred->BindExit();
2668
2669 // Push the object literal boilerplate.
2670 frame_->EmitPush(r2);
2671
2672 // Clone the boilerplate object.
2673 Runtime::FunctionId clone_function_id = Runtime::kCloneLiteralBoilerplate;
2674 if (node->depth() == 1) {
2675 clone_function_id = Runtime::kCloneShallowLiteralBoilerplate;
2676 } 2624 }
2677 frame_->CallRuntime(clone_function_id, 1);
2678 frame_->EmitPush(r0); // save the result 2625 frame_->EmitPush(r0); // save the result
2679 // r0: cloned object literal 2626 // r0: created object literal
2680 2627
2681 for (int i = 0; i < node->properties()->length(); i++) { 2628 for (int i = 0; i < node->properties()->length(); i++) {
2682 ObjectLiteral::Property* property = node->properties()->at(i); 2629 ObjectLiteral::Property* property = node->properties()->at(i);
2683 Literal* key = property->key(); 2630 Literal* key = property->key();
2684 Expression* value = property->value(); 2631 Expression* value = property->value();
2685 switch (property->kind()) { 2632 switch (property->kind()) {
2686 case ObjectLiteral::Property::CONSTANT: 2633 case ObjectLiteral::Property::CONSTANT:
2687 break; 2634 break;
2688 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 2635 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2689 if (CompileTimeValue::IsCompileTimeValue(property->value())) break; 2636 if (CompileTimeValue::IsCompileTimeValue(property->value())) break;
(...skipping 27 matching lines...) Expand all
2717 frame_->CallRuntime(Runtime::kDefineAccessor, 4); 2664 frame_->CallRuntime(Runtime::kDefineAccessor, 4);
2718 __ ldr(r0, frame_->Top()); 2665 __ ldr(r0, frame_->Top());
2719 break; 2666 break;
2720 } 2667 }
2721 } 2668 }
2722 } 2669 }
2723 ASSERT(frame_->height() == original_height + 1); 2670 ASSERT(frame_->height() == original_height + 1);
2724 } 2671 }
2725 2672
2726 2673
2727 // This deferred code stub will be used for creating the boilerplate
2728 // by calling Runtime_CreateArrayLiteralBoilerplate.
2729 // Each created boilerplate is stored in the JSFunction and they are
2730 // therefore context dependent.
2731 class DeferredArrayLiteral: public DeferredCode {
2732 public:
2733 explicit DeferredArrayLiteral(ArrayLiteral* node) : node_(node) {
2734 set_comment("[ DeferredArrayLiteral");
2735 }
2736
2737 virtual void Generate();
2738
2739 private:
2740 ArrayLiteral* node_;
2741 };
2742
2743
2744 void DeferredArrayLiteral::Generate() {
2745 // Argument is passed in r1.
2746
2747 // If the entry is undefined we call the runtime system to computed
2748 // the literal.
2749 // Literal array (0).
2750 __ push(r1);
2751 // Literal index (1).
2752 __ mov(r0, Operand(Smi::FromInt(node_->literal_index())));
2753 __ push(r0);
2754 // Constant properties (2).
2755 __ mov(r0, Operand(node_->literals()));
2756 __ push(r0);
2757 __ CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3);
2758 __ mov(r2, Operand(r0));
2759 // Result is returned in r2.
2760 }
2761
2762
2763 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { 2674 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
2764 #ifdef DEBUG 2675 #ifdef DEBUG
2765 int original_height = frame_->height(); 2676 int original_height = frame_->height();
2766 #endif 2677 #endif
2767 VirtualFrame::SpilledScope spilled_scope; 2678 VirtualFrame::SpilledScope spilled_scope;
2768 Comment cmnt(masm_, "[ ArrayLiteral"); 2679 Comment cmnt(masm_, "[ ArrayLiteral");
2769 2680
2770 DeferredArrayLiteral* deferred = new DeferredArrayLiteral(node);
2771
2772 // Retrieve the literal array and check the allocated entry.
2773
2774 // Load the function of this activation. 2681 // Load the function of this activation.
2775 __ ldr(r1, frame_->Function()); 2682 __ ldr(r2, frame_->Function());
2776 2683 // Literals array.
2777 // Load the literals array of the function. 2684 __ ldr(r2, FieldMemOperand(r2, JSFunction::kLiteralsOffset));
2778 __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset)); 2685 // Literal index.
2779 2686 __ mov(r1, Operand(Smi::FromInt(node->literal_index())));
2780 // Load the literal at the ast saved index. 2687 // Constant elements.
2781 int literal_offset = 2688 __ mov(r0, Operand(node->constant_elements()));
2782 FixedArray::kHeaderSize + node->literal_index() * kPointerSize; 2689 frame_->EmitPushMultiple(3, r2.bit() | r1.bit() | r0.bit());
2783 __ ldr(r2, FieldMemOperand(r1, literal_offset)); 2690 if (node->depth() > 1) {
2784 2691 frame_->CallRuntime(Runtime::kCreateArrayLiteral, 3);
2785 // Check whether we need to materialize the object literal boilerplate. 2692 } else {
2786 // If so, jump to the deferred code. 2693 frame_->CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
2787 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
2788 __ cmp(r2, Operand(ip));
2789 deferred->Branch(eq);
2790 deferred->BindExit();
2791
2792 // Push the object literal boilerplate.
2793 frame_->EmitPush(r2);
2794
2795 // Clone the boilerplate object.
2796 Runtime::FunctionId clone_function_id = Runtime::kCloneLiteralBoilerplate;
2797 if (node->depth() == 1) {
2798 clone_function_id = Runtime::kCloneShallowLiteralBoilerplate;
2799 } 2694 }
2800 frame_->CallRuntime(clone_function_id, 1);
2801 frame_->EmitPush(r0); // save the result 2695 frame_->EmitPush(r0); // save the result
2802 // r0: cloned object literal 2696 // r0: created object literal
2803 2697
2804 // Generate code to set the elements in the array that are not 2698 // Generate code to set the elements in the array that are not
2805 // literals. 2699 // literals.
2806 for (int i = 0; i < node->values()->length(); i++) { 2700 for (int i = 0; i < node->values()->length(); i++) {
2807 Expression* value = node->values()->at(i); 2701 Expression* value = node->values()->at(i);
2808 2702
2809 // If value is a literal the property value is already set in the 2703 // If value is a literal the property value is already set in the
2810 // boilerplate object. 2704 // boilerplate object.
2811 if (value->AsLiteral() != NULL) continue; 2705 if (value->AsLiteral() != NULL) continue;
2812 // If value is a materialized literal the property value is already set 2706 // If value is a materialized literal the property value is already set
(...skipping 3756 matching lines...) Expand 10 before | Expand all | Expand 10 after
6569 int CompareStub::MinorKey() { 6463 int CompareStub::MinorKey() {
6570 // Encode the two parameters in a unique 16 bit value. 6464 // Encode the two parameters in a unique 16 bit value.
6571 ASSERT(static_cast<unsigned>(cc_) >> 28 < (1 << 15)); 6465 ASSERT(static_cast<unsigned>(cc_) >> 28 < (1 << 15));
6572 return (static_cast<unsigned>(cc_) >> 27) | (strict_ ? 1 : 0); 6466 return (static_cast<unsigned>(cc_) >> 27) | (strict_ ? 1 : 0);
6573 } 6467 }
6574 6468
6575 6469
6576 #undef __ 6470 #undef __
6577 6471
6578 } } // namespace v8::internal 6472 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/arm/fast-codegen-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698