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

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

Issue 40295: Optimizing generation of nested literals for both object and array literals. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 9 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 | « src/ast.cc ('k') | src/codegen-ia32.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-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 2601 matching lines...) Expand 10 before | Expand all | Expand 10 after
2612 __ mov(r2, Operand(r0)); 2612 __ mov(r2, Operand(r0));
2613 2613
2614 done.Bind(); 2614 done.Bind();
2615 // Push the literal. 2615 // Push the literal.
2616 frame_->EmitPush(r2); 2616 frame_->EmitPush(r2);
2617 ASSERT(frame_->height() == original_height + 1); 2617 ASSERT(frame_->height() == original_height + 1);
2618 } 2618 }
2619 2619
2620 2620
2621 // This deferred code stub will be used for creating the boilerplate 2621 // This deferred code stub will be used for creating the boilerplate
2622 // by calling Runtime_CreateObjectLiteral. 2622 // by calling Runtime_CreateObjectLiteralBoilerplate.
2623 // Each created boilerplate is stored in the JSFunction and they are 2623 // Each created boilerplate is stored in the JSFunction and they are
2624 // therefore context dependent. 2624 // therefore context dependent.
2625 class DeferredObjectLiteral: public DeferredCode { 2625 class DeferredObjectLiteral: public DeferredCode {
2626 public: 2626 public:
2627 DeferredObjectLiteral(CodeGenerator* generator, ObjectLiteral* node) 2627 DeferredObjectLiteral(CodeGenerator* generator, ObjectLiteral* node)
2628 : DeferredCode(generator), node_(node) { 2628 : DeferredCode(generator), node_(node) {
2629 set_comment("[ DeferredObjectLiteral"); 2629 set_comment("[ DeferredObjectLiteral");
2630 } 2630 }
2631 2631
2632 virtual void Generate(); 2632 virtual void Generate();
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2686 // Check whether we need to materialize the object literal boilerplate. 2686 // Check whether we need to materialize the object literal boilerplate.
2687 // If so, jump to the deferred code. 2687 // If so, jump to the deferred code.
2688 __ cmp(r2, Operand(Factory::undefined_value())); 2688 __ cmp(r2, Operand(Factory::undefined_value()));
2689 deferred->enter()->Branch(eq); 2689 deferred->enter()->Branch(eq);
2690 deferred->BindExit(); 2690 deferred->BindExit();
2691 2691
2692 // Push the object literal boilerplate. 2692 // Push the object literal boilerplate.
2693 frame_->EmitPush(r2); 2693 frame_->EmitPush(r2);
2694 2694
2695 // Clone the boilerplate object. 2695 // Clone the boilerplate object.
2696 frame_->CallRuntime(Runtime::kCloneObjectLiteralBoilerplate, 1); 2696 frame_->CallRuntime(Runtime::kCloneLiteralBoilerplate, 1);
2697 frame_->EmitPush(r0); // save the result 2697 frame_->EmitPush(r0); // save the result
2698 // r0: cloned object literal 2698 // r0: cloned object literal
2699 2699
2700 for (int i = 0; i < node->properties()->length(); i++) { 2700 for (int i = 0; i < node->properties()->length(); i++) {
2701 ObjectLiteral::Property* property = node->properties()->at(i); 2701 ObjectLiteral::Property* property = node->properties()->at(i);
2702 Literal* key = property->key(); 2702 Literal* key = property->key();
2703 Expression* value = property->value(); 2703 Expression* value = property->value();
2704 switch (property->kind()) { 2704 switch (property->kind()) {
2705 case ObjectLiteral::Property::CONSTANT: break; 2705 case ObjectLiteral::Property::CONSTANT:
2706 case ObjectLiteral::Property::OBJECT_LITERAL: 2706 break;
2707 if (property->value()->AsObjectLiteral()->is_simple()) break; 2707 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2708 if (property->value()->AsMaterializedLiteral()->is_simple()) break;
2709 // else fall through
2708 case ObjectLiteral::Property::COMPUTED: // fall through 2710 case ObjectLiteral::Property::COMPUTED: // fall through
2709 case ObjectLiteral::Property::PROTOTYPE: { 2711 case ObjectLiteral::Property::PROTOTYPE: {
2710 frame_->EmitPush(r0); // dup the result 2712 frame_->EmitPush(r0); // dup the result
2711 LoadAndSpill(key); 2713 LoadAndSpill(key);
2712 LoadAndSpill(value); 2714 LoadAndSpill(value);
2713 frame_->CallRuntime(Runtime::kSetProperty, 3); 2715 frame_->CallRuntime(Runtime::kSetProperty, 3);
2714 // restore r0 2716 // restore r0
2715 __ ldr(r0, frame_->Top()); 2717 __ ldr(r0, frame_->Top());
2716 break; 2718 break;
2717 } 2719 }
(...skipping 16 matching lines...) Expand all
2734 frame_->CallRuntime(Runtime::kDefineAccessor, 4); 2736 frame_->CallRuntime(Runtime::kDefineAccessor, 4);
2735 __ ldr(r0, frame_->Top()); 2737 __ ldr(r0, frame_->Top());
2736 break; 2738 break;
2737 } 2739 }
2738 } 2740 }
2739 } 2741 }
2740 ASSERT(frame_->height() == original_height + 1); 2742 ASSERT(frame_->height() == original_height + 1);
2741 } 2743 }
2742 2744
2743 2745
2746 // This deferred code stub will be used for creating the boilerplate
2747 // by calling Runtime_CreateArrayLiteralBoilerplate.
2748 // Each created boilerplate is stored in the JSFunction and they are
2749 // therefore context dependent.
2750 class DeferredArrayLiteral: public DeferredCode {
2751 public:
2752 DeferredArrayLiteral(CodeGenerator* generator, ArrayLiteral* node)
2753 : DeferredCode(generator), node_(node) {
2754 set_comment("[ DeferredArrayLiteral");
2755 }
2756
2757 virtual void Generate();
2758
2759 private:
2760 ArrayLiteral* node_;
2761 };
2762
2763
2764 void DeferredArrayLiteral::Generate() {
2765 // Argument is passed in r1.
2766 enter()->Bind();
2767 VirtualFrame::SpilledScope spilled_scope(generator());
2768
2769 // If the entry is undefined we call the runtime system to computed
2770 // the literal.
2771
2772 VirtualFrame* frame = generator()->frame();
2773 // Literal array (0).
2774 frame->EmitPush(r1);
2775 // Literal index (1).
2776 __ mov(r0, Operand(Smi::FromInt(node_->literal_index())));
2777 frame->EmitPush(r0);
2778 // Constant properties (2).
2779 __ mov(r0, Operand(node_->literals()));
2780 frame->EmitPush(r0);
2781 Result boilerplate =
2782 frame->CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3);
2783 __ mov(r2, Operand(boilerplate.reg()));
2784 // Result is returned in r2.
2785 exit_.Jump();
2786 }
2787
2788
2744 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { 2789 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
2745 #ifdef DEBUG 2790 #ifdef DEBUG
2746 int original_height = frame_->height(); 2791 int original_height = frame_->height();
2747 #endif 2792 #endif
2748 VirtualFrame::SpilledScope spilled_scope(this); 2793 VirtualFrame::SpilledScope spilled_scope(this);
2749 Comment cmnt(masm_, "[ ArrayLiteral"); 2794 Comment cmnt(masm_, "[ ArrayLiteral");
2750 2795
2751 // Call runtime to create the array literal. 2796 DeferredArrayLiteral* deferred = new DeferredArrayLiteral(this, node);
2752 __ mov(r0, Operand(node->literals()));
2753 frame_->EmitPush(r0);
2754 // Load the function of this frame.
2755 __ ldr(r0, frame_->Function());
2756 __ ldr(r0, FieldMemOperand(r0, JSFunction::kLiteralsOffset));
2757 frame_->EmitPush(r0);
2758 frame_->CallRuntime(Runtime::kCreateArrayLiteral, 2);
2759 2797
2760 // Push the resulting array literal on the stack. 2798 // Retrieve the literal array and check the allocated entry.
2761 frame_->EmitPush(r0); 2799
2800 // Load the function of this activation.
2801 __ ldr(r1, frame_->Function());
2802
2803 // Load the literals array of the function.
2804 __ ldr(r1, FieldMemOperand(r1, JSFunction::kLiteralsOffset));
2805
2806 // Load the literal at the ast saved index.
2807 int literal_offset =
2808 FixedArray::kHeaderSize + node->literal_index() * kPointerSize;
2809 __ ldr(r2, FieldMemOperand(r1, literal_offset));
2810
2811 // Check whether we need to materialize the object literal boilerplate.
2812 // If so, jump to the deferred code.
2813 __ cmp(r2, Operand(Factory::undefined_value()));
2814 deferred->enter()->Branch(eq);
2815 deferred->BindExit();
2816
2817 // Push the object literal boilerplate.
2818 frame_->EmitPush(r2);
2819
2820 // Clone the boilerplate object.
2821 frame_->CallRuntime(Runtime::kCloneLiteralBoilerplate, 1);
2822 frame_->EmitPush(r0); // save the result
2823 // r0: cloned object literal
2762 2824
2763 // Generate code to set the elements in the array that are not 2825 // Generate code to set the elements in the array that are not
2764 // literals. 2826 // literals.
2765 for (int i = 0; i < node->values()->length(); i++) { 2827 for (int i = 0; i < node->values()->length(); i++) {
2766 Expression* value = node->values()->at(i); 2828 Expression* value = node->values()->at(i);
2767 2829
2768 // If value is literal the property value is already 2830 // If value is literal the property value is already
2769 // set in the boilerplate object. 2831 // set in the boilerplate object.
2770 if (value->AsLiteral() == NULL) { 2832 if (value->AsLiteral() == NULL) {
2771 // The property must be set by generated code. 2833 // The property must be set by generated code.
(...skipping 2323 matching lines...) Expand 10 before | Expand all | Expand 10 after
5095 __ mov(r2, Operand(0)); 5157 __ mov(r2, Operand(0));
5096 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); 5158 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
5097 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), 5159 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)),
5098 RelocInfo::CODE_TARGET); 5160 RelocInfo::CODE_TARGET);
5099 } 5161 }
5100 5162
5101 5163
5102 #undef __ 5164 #undef __
5103 5165
5104 } } // namespace v8::internal 5166 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ast.cc ('k') | src/codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698