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

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

Issue 660095: Merge revision 3813 to 3930 from bleeding_edge to partial snapshots branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
Patch Set: '' Created 10 years, 10 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/arm/codegen-arm.h ('k') | src/arm/debug-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 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 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 135
136 Scope* CodeGenerator::scope() { return info_->function()->scope(); } 136 Scope* CodeGenerator::scope() { return info_->function()->scope(); }
137 137
138 138
139 // Calling conventions: 139 // Calling conventions:
140 // fp: caller's frame pointer 140 // fp: caller's frame pointer
141 // sp: stack pointer 141 // sp: stack pointer
142 // r1: called JS function 142 // r1: called JS function
143 // cp: callee's context 143 // cp: callee's context
144 144
145 void CodeGenerator::Generate(CompilationInfo* info, Mode mode) { 145 void CodeGenerator::Generate(CompilationInfo* info) {
146 // Record the position for debugging purposes. 146 // Record the position for debugging purposes.
147 CodeForFunctionPosition(info->function()); 147 CodeForFunctionPosition(info->function());
148 148
149 // Initialize state. 149 // Initialize state.
150 info_ = info; 150 info_ = info;
151 ASSERT(allocator_ == NULL); 151 ASSERT(allocator_ == NULL);
152 RegisterAllocator register_allocator(this); 152 RegisterAllocator register_allocator(this);
153 allocator_ = &register_allocator; 153 allocator_ = &register_allocator;
154 ASSERT(frame_ == NULL); 154 ASSERT(frame_ == NULL);
155 frame_ = new VirtualFrame(); 155 frame_ = new VirtualFrame();
(...skipping 11 matching lines...) Expand all
167 allocator_->Initialize(); 167 allocator_->Initialize();
168 168
169 #ifdef DEBUG 169 #ifdef DEBUG
170 if (strlen(FLAG_stop_at) > 0 && 170 if (strlen(FLAG_stop_at) > 0 &&
171 info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { 171 info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
172 frame_->SpillAll(); 172 frame_->SpillAll();
173 __ stop("stop-at"); 173 __ stop("stop-at");
174 } 174 }
175 #endif 175 #endif
176 176
177 if (mode == PRIMARY) { 177 if (info->mode() == CompilationInfo::PRIMARY) {
178 frame_->Enter(); 178 frame_->Enter();
179 // tos: code slot 179 // tos: code slot
180 180
181 // Allocate space for locals and initialize them. This also checks 181 // Allocate space for locals and initialize them. This also checks
182 // for stack overflow. 182 // for stack overflow.
183 frame_->AllocateStackSlots(); 183 frame_->AllocateStackSlots();
184 184
185 VirtualFrame::SpilledScope spilled_scope; 185 VirtualFrame::SpilledScope spilled_scope;
186 int heap_slots = scope()->num_heap_slots(); 186 int heap_slots = scope()->num_heap_slots();
187 if (heap_slots > 0) { 187 if (heap_slots > 0) {
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 frame_->EmitPush(ip); 270 frame_->EmitPush(ip);
271 StoreToSlot(scope()->function()->slot(), NOT_CONST_INIT); 271 StoreToSlot(scope()->function()->slot(), NOT_CONST_INIT);
272 } 272 }
273 } else { 273 } else {
274 // When used as the secondary compiler for splitting, r1, cp, 274 // When used as the secondary compiler for splitting, r1, cp,
275 // fp, and lr have been pushed on the stack. Adjust the virtual 275 // fp, and lr have been pushed on the stack. Adjust the virtual
276 // frame to match this state. 276 // frame to match this state.
277 frame_->Adjust(4); 277 frame_->Adjust(4);
278 allocator_->Unuse(r1); 278 allocator_->Unuse(r1);
279 allocator_->Unuse(lr); 279 allocator_->Unuse(lr);
280
281 // Bind all the bailout labels to the beginning of the function.
282 List<CompilationInfo::Bailout*>* bailouts = info->bailouts();
283 for (int i = 0; i < bailouts->length(); i++) {
284 __ bind(bailouts->at(i)->label());
285 }
280 } 286 }
281 287
282 // Initialize the function return target after the locals are set 288 // Initialize the function return target after the locals are set
283 // up, because it needs the expected frame height from the frame. 289 // up, because it needs the expected frame height from the frame.
284 function_return_.set_direction(JumpTarget::BIDIRECTIONAL); 290 function_return_.set_direction(JumpTarget::BIDIRECTIONAL);
285 function_return_is_shadowed_ = false; 291 function_return_is_shadowed_ = false;
286 292
287 // Generate code to 'execute' declarations and initialize functions 293 // Generate code to 'execute' declarations and initialize functions
288 // (source elements). In case of an illegal redeclaration we need to 294 // (source elements). In case of an illegal redeclaration we need to
289 // handle that instead of processing the declarations. 295 // handle that instead of processing the declarations.
(...skipping 1996 matching lines...) Expand 10 before | Expand all | Expand 10 after
2286 2292
2287 2293
2288 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) { 2294 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) {
2289 #ifdef DEBUG 2295 #ifdef DEBUG
2290 int original_height = frame_->height(); 2296 int original_height = frame_->height();
2291 #endif 2297 #endif
2292 VirtualFrame::SpilledScope spilled_scope; 2298 VirtualFrame::SpilledScope spilled_scope;
2293 Comment cmnt(masm_, "[ DebuggerStatament"); 2299 Comment cmnt(masm_, "[ DebuggerStatament");
2294 CodeForStatementPosition(node); 2300 CodeForStatementPosition(node);
2295 #ifdef ENABLE_DEBUGGER_SUPPORT 2301 #ifdef ENABLE_DEBUGGER_SUPPORT
2296 DebuggerStatementStub ces; 2302 frame_->DebugBreak();
2297 frame_->CallStub(&ces, 0);
2298 #endif 2303 #endif
2299 // Ignore the return value. 2304 // Ignore the return value.
2300 ASSERT(frame_->height() == original_height); 2305 ASSERT(frame_->height() == original_height);
2301 } 2306 }
2302 2307
2303 2308
2304 void CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) { 2309 void CodeGenerator::InstantiateBoilerplate(Handle<JSFunction> boilerplate) {
2305 VirtualFrame::SpilledScope spilled_scope; 2310 VirtualFrame::SpilledScope spilled_scope;
2306 ASSERT(boilerplate->IsBoilerplate()); 2311 ASSERT(boilerplate->IsBoilerplate());
2307 2312
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
2712 __ mov(r1, Operand(Smi::FromInt(node->literal_index()))); 2717 __ mov(r1, Operand(Smi::FromInt(node->literal_index())));
2713 // Constant properties. 2718 // Constant properties.
2714 __ mov(r0, Operand(node->constant_properties())); 2719 __ mov(r0, Operand(node->constant_properties()));
2715 frame_->EmitPushMultiple(3, r2.bit() | r1.bit() | r0.bit()); 2720 frame_->EmitPushMultiple(3, r2.bit() | r1.bit() | r0.bit());
2716 if (node->depth() > 1) { 2721 if (node->depth() > 1) {
2717 frame_->CallRuntime(Runtime::kCreateObjectLiteral, 3); 2722 frame_->CallRuntime(Runtime::kCreateObjectLiteral, 3);
2718 } else { 2723 } else {
2719 frame_->CallRuntime(Runtime::kCreateObjectLiteralShallow, 3); 2724 frame_->CallRuntime(Runtime::kCreateObjectLiteralShallow, 3);
2720 } 2725 }
2721 frame_->EmitPush(r0); // save the result 2726 frame_->EmitPush(r0); // save the result
2722 // r0: created object literal
2723
2724 for (int i = 0; i < node->properties()->length(); i++) { 2727 for (int i = 0; i < node->properties()->length(); i++) {
2728 // At the start of each iteration, the top of stack contains
2729 // the newly created object literal.
2725 ObjectLiteral::Property* property = node->properties()->at(i); 2730 ObjectLiteral::Property* property = node->properties()->at(i);
2726 Literal* key = property->key(); 2731 Literal* key = property->key();
2727 Expression* value = property->value(); 2732 Expression* value = property->value();
2728 switch (property->kind()) { 2733 switch (property->kind()) {
2729 case ObjectLiteral::Property::CONSTANT: 2734 case ObjectLiteral::Property::CONSTANT:
2730 break; 2735 break;
2731 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 2736 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2732 if (CompileTimeValue::IsCompileTimeValue(property->value())) break; 2737 if (CompileTimeValue::IsCompileTimeValue(property->value())) break;
2733 // else fall through 2738 // else fall through
2734 case ObjectLiteral::Property::COMPUTED: // fall through 2739 case ObjectLiteral::Property::COMPUTED:
2740 if (key->handle()->IsSymbol()) {
2741 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
2742 LoadAndSpill(value);
2743 frame_->EmitPop(r0);
2744 __ mov(r2, Operand(key->handle()));
2745 __ ldr(r1, frame_->Top()); // Load the receiver.
2746 frame_->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
2747 break;
2748 }
2749 // else fall through
2735 case ObjectLiteral::Property::PROTOTYPE: { 2750 case ObjectLiteral::Property::PROTOTYPE: {
2751 __ ldr(r0, frame_->Top());
2736 frame_->EmitPush(r0); // dup the result 2752 frame_->EmitPush(r0); // dup the result
2737 LoadAndSpill(key); 2753 LoadAndSpill(key);
2738 LoadAndSpill(value); 2754 LoadAndSpill(value);
2739 frame_->CallRuntime(Runtime::kSetProperty, 3); 2755 frame_->CallRuntime(Runtime::kSetProperty, 3);
2740 // restore r0
2741 __ ldr(r0, frame_->Top());
2742 break; 2756 break;
2743 } 2757 }
2744 case ObjectLiteral::Property::SETTER: { 2758 case ObjectLiteral::Property::SETTER: {
2759 __ ldr(r0, frame_->Top());
2745 frame_->EmitPush(r0); 2760 frame_->EmitPush(r0);
2746 LoadAndSpill(key); 2761 LoadAndSpill(key);
2747 __ mov(r0, Operand(Smi::FromInt(1))); 2762 __ mov(r0, Operand(Smi::FromInt(1)));
2748 frame_->EmitPush(r0); 2763 frame_->EmitPush(r0);
2749 LoadAndSpill(value); 2764 LoadAndSpill(value);
2750 frame_->CallRuntime(Runtime::kDefineAccessor, 4); 2765 frame_->CallRuntime(Runtime::kDefineAccessor, 4);
2751 __ ldr(r0, frame_->Top());
2752 break; 2766 break;
2753 } 2767 }
2754 case ObjectLiteral::Property::GETTER: { 2768 case ObjectLiteral::Property::GETTER: {
2769 __ ldr(r0, frame_->Top());
2755 frame_->EmitPush(r0); 2770 frame_->EmitPush(r0);
2756 LoadAndSpill(key); 2771 LoadAndSpill(key);
2757 __ mov(r0, Operand(Smi::FromInt(0))); 2772 __ mov(r0, Operand(Smi::FromInt(0)));
2758 frame_->EmitPush(r0); 2773 frame_->EmitPush(r0);
2759 LoadAndSpill(value); 2774 LoadAndSpill(value);
2760 frame_->CallRuntime(Runtime::kDefineAccessor, 4); 2775 frame_->CallRuntime(Runtime::kDefineAccessor, 4);
2761 __ ldr(r0, frame_->Top());
2762 break; 2776 break;
2763 } 2777 }
2764 } 2778 }
2765 } 2779 }
2766 ASSERT(frame_->height() == original_height + 1); 2780 ASSERT(frame_->height() == original_height + 1);
2767 } 2781 }
2768 2782
2769 2783
2770 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { 2784 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
2771 #ifdef DEBUG 2785 #ifdef DEBUG
2772 int original_height = frame_->height(); 2786 int original_height = frame_->height();
2773 #endif 2787 #endif
2774 VirtualFrame::SpilledScope spilled_scope; 2788 VirtualFrame::SpilledScope spilled_scope;
2775 Comment cmnt(masm_, "[ ArrayLiteral"); 2789 Comment cmnt(masm_, "[ ArrayLiteral");
2776 2790
2777 // Load the function of this activation. 2791 // Load the function of this activation.
2778 __ ldr(r2, frame_->Function()); 2792 __ ldr(r2, frame_->Function());
2779 // Literals array. 2793 // Load the literals array of the function.
2780 __ ldr(r2, FieldMemOperand(r2, JSFunction::kLiteralsOffset)); 2794 __ ldr(r2, FieldMemOperand(r2, JSFunction::kLiteralsOffset));
2781 // Literal index.
2782 __ mov(r1, Operand(Smi::FromInt(node->literal_index()))); 2795 __ mov(r1, Operand(Smi::FromInt(node->literal_index())));
2783 // Constant elements.
2784 __ mov(r0, Operand(node->constant_elements())); 2796 __ mov(r0, Operand(node->constant_elements()));
2785 frame_->EmitPushMultiple(3, r2.bit() | r1.bit() | r0.bit()); 2797 frame_->EmitPushMultiple(3, r2.bit() | r1.bit() | r0.bit());
2798 int length = node->values()->length();
2786 if (node->depth() > 1) { 2799 if (node->depth() > 1) {
2787 frame_->CallRuntime(Runtime::kCreateArrayLiteral, 3); 2800 frame_->CallRuntime(Runtime::kCreateArrayLiteral, 3);
2801 } else if (length > FastCloneShallowArrayStub::kMaximumLength) {
2802 frame_->CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
2788 } else { 2803 } else {
2789 frame_->CallRuntime(Runtime::kCreateArrayLiteralShallow, 3); 2804 FastCloneShallowArrayStub stub(length);
2805 frame_->CallStub(&stub, 3);
2790 } 2806 }
2791 frame_->EmitPush(r0); // save the result 2807 frame_->EmitPush(r0); // save the result
2792 // r0: created object literal 2808 // r0: created object literal
2793 2809
2794 // Generate code to set the elements in the array that are not 2810 // Generate code to set the elements in the array that are not
2795 // literals. 2811 // literals.
2796 for (int i = 0; i < node->values()->length(); i++) { 2812 for (int i = 0; i < node->values()->length(); i++) {
2797 Expression* value = node->values()->at(i); 2813 Expression* value = node->values()->at(i);
2798 2814
2799 // If value is a literal the property value is already set in the 2815 // If value is a literal the property value is already set in the
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
3006 3022
3007 __ ldr(cp, frame_->Context()); 3023 __ ldr(cp, frame_->Context());
3008 // Remove the function from the stack. 3024 // Remove the function from the stack.
3009 frame_->Drop(); 3025 frame_->Drop();
3010 frame_->EmitPush(r0); 3026 frame_->EmitPush(r0);
3011 3027
3012 } else if (var != NULL && !var->is_this() && var->is_global()) { 3028 } else if (var != NULL && !var->is_this() && var->is_global()) {
3013 // ---------------------------------- 3029 // ----------------------------------
3014 // JavaScript example: 'foo(1, 2, 3)' // foo is global 3030 // JavaScript example: 'foo(1, 2, 3)' // foo is global
3015 // ---------------------------------- 3031 // ----------------------------------
3016
3017 // Push the name of the function and the receiver onto the stack.
3018 __ mov(r0, Operand(var->name()));
3019 frame_->EmitPush(r0);
3020
3021 // Pass the global object as the receiver and let the IC stub 3032 // Pass the global object as the receiver and let the IC stub
3022 // patch the stack to use the global proxy as 'this' in the 3033 // patch the stack to use the global proxy as 'this' in the
3023 // invoked function. 3034 // invoked function.
3024 LoadGlobal(); 3035 LoadGlobal();
3025 3036
3026 // Load the arguments. 3037 // Load the arguments.
3027 int arg_count = args->length(); 3038 int arg_count = args->length();
3028 for (int i = 0; i < arg_count; i++) { 3039 for (int i = 0; i < arg_count; i++) {
3029 LoadAndSpill(args->at(i)); 3040 LoadAndSpill(args->at(i));
3030 } 3041 }
3031 3042
3032 // Setup the receiver register and call the IC initialization code. 3043 // Setup the name register and call the IC initialization code.
3044 __ mov(r2, Operand(var->name()));
3033 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP; 3045 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
3034 Handle<Code> stub = ComputeCallInitialize(arg_count, in_loop); 3046 Handle<Code> stub = ComputeCallInitialize(arg_count, in_loop);
3035 CodeForSourcePosition(node->position()); 3047 CodeForSourcePosition(node->position());
3036 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET_CONTEXT, 3048 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET_CONTEXT,
3037 arg_count + 1); 3049 arg_count + 1);
3038 __ ldr(cp, frame_->Context()); 3050 __ ldr(cp, frame_->Context());
3039 // Remove the function from the stack.
3040 frame_->Drop();
3041 frame_->EmitPush(r0); 3051 frame_->EmitPush(r0);
3042 3052
3043 } else if (var != NULL && var->slot() != NULL && 3053 } else if (var != NULL && var->slot() != NULL &&
3044 var->slot()->type() == Slot::LOOKUP) { 3054 var->slot()->type() == Slot::LOOKUP) {
3045 // ---------------------------------- 3055 // ----------------------------------
3046 // JavaScript example: 'with (obj) foo(1, 2, 3)' // foo is in obj 3056 // JavaScript example: 'with (obj) foo(1, 2, 3)' // foo is in obj
3047 // ---------------------------------- 3057 // ----------------------------------
3048 3058
3049 // Load the function 3059 // Load the function
3050 frame_->EmitPush(cp); 3060 frame_->EmitPush(cp);
(...skipping 12 matching lines...) Expand all
3063 3073
3064 } else if (property != NULL) { 3074 } else if (property != NULL) {
3065 // Check if the key is a literal string. 3075 // Check if the key is a literal string.
3066 Literal* literal = property->key()->AsLiteral(); 3076 Literal* literal = property->key()->AsLiteral();
3067 3077
3068 if (literal != NULL && literal->handle()->IsSymbol()) { 3078 if (literal != NULL && literal->handle()->IsSymbol()) {
3069 // ------------------------------------------------------------------ 3079 // ------------------------------------------------------------------
3070 // JavaScript example: 'object.foo(1, 2, 3)' or 'map["key"](1, 2, 3)' 3080 // JavaScript example: 'object.foo(1, 2, 3)' or 'map["key"](1, 2, 3)'
3071 // ------------------------------------------------------------------ 3081 // ------------------------------------------------------------------
3072 3082
3073 // Push the name of the function and the receiver onto the stack. 3083 LoadAndSpill(property->obj()); // Receiver.
3074 __ mov(r0, Operand(literal->handle()));
3075 frame_->EmitPush(r0);
3076 LoadAndSpill(property->obj());
3077
3078 // Load the arguments. 3084 // Load the arguments.
3079 int arg_count = args->length(); 3085 int arg_count = args->length();
3080 for (int i = 0; i < arg_count; i++) { 3086 for (int i = 0; i < arg_count; i++) {
3081 LoadAndSpill(args->at(i)); 3087 LoadAndSpill(args->at(i));
3082 } 3088 }
3083 3089
3084 // Set the receiver register and call the IC initialization code. 3090 // Set the name register and call the IC initialization code.
3091 __ mov(r2, Operand(literal->handle()));
3085 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP; 3092 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
3086 Handle<Code> stub = ComputeCallInitialize(arg_count, in_loop); 3093 Handle<Code> stub = ComputeCallInitialize(arg_count, in_loop);
3087 CodeForSourcePosition(node->position()); 3094 CodeForSourcePosition(node->position());
3088 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET, arg_count + 1); 3095 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET, arg_count + 1);
3089 __ ldr(cp, frame_->Context()); 3096 __ ldr(cp, frame_->Context());
3090 3097 frame_->EmitPush(r0);
3091 // Remove the function from the stack.
3092 frame_->Drop();
3093
3094 frame_->EmitPush(r0); // push after get rid of function from the stack
3095 3098
3096 } else { 3099 } else {
3097 // ------------------------------------------- 3100 // -------------------------------------------
3098 // JavaScript example: 'array[index](1, 2, 3)' 3101 // JavaScript example: 'array[index](1, 2, 3)'
3099 // ------------------------------------------- 3102 // -------------------------------------------
3100 3103
3101 LoadAndSpill(property->obj()); 3104 LoadAndSpill(property->obj());
3102 LoadAndSpill(property->key()); 3105 LoadAndSpill(property->key());
3103 EmitKeyedLoad(false); 3106 EmitKeyedLoad(false);
3104 frame_->Drop(); // key 3107 frame_->Drop(); // key
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
3416 __ and_(r1, r0, Operand(kSmiTagMask)); 3419 __ and_(r1, r0, Operand(kSmiTagMask));
3417 __ eor(r1, r1, Operand(kSmiTagMask), SetCC); 3420 __ eor(r1, r1, Operand(kSmiTagMask), SetCC);
3418 answer.Branch(ne); 3421 answer.Branch(ne);
3419 // It is a heap object - get the map. Check if the object is a JS array. 3422 // It is a heap object - get the map. Check if the object is a JS array.
3420 __ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE); 3423 __ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE);
3421 answer.Bind(); 3424 answer.Bind();
3422 cc_reg_ = eq; 3425 cc_reg_ = eq;
3423 } 3426 }
3424 3427
3425 3428
3429 void CodeGenerator::GenerateIsRegExp(ZoneList<Expression*>* args) {
3430 VirtualFrame::SpilledScope spilled_scope;
3431 ASSERT(args->length() == 1);
3432 LoadAndSpill(args->at(0));
3433 JumpTarget answer;
3434 // We need the CC bits to come out as not_equal in the case where the
3435 // object is a smi. This can't be done with the usual test opcode so
3436 // we use XOR to get the right CC bits.
3437 frame_->EmitPop(r0);
3438 __ and_(r1, r0, Operand(kSmiTagMask));
3439 __ eor(r1, r1, Operand(kSmiTagMask), SetCC);
3440 answer.Branch(ne);
3441 // It is a heap object - get the map. Check if the object is a regexp.
3442 __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE);
3443 answer.Bind();
3444 cc_reg_ = eq;
3445 }
3446
3447
3426 void CodeGenerator::GenerateIsObject(ZoneList<Expression*>* args) { 3448 void CodeGenerator::GenerateIsObject(ZoneList<Expression*>* args) {
3427 // This generates a fast version of: 3449 // This generates a fast version of:
3428 // (typeof(arg) === 'object' || %_ClassOf(arg) == 'RegExp') 3450 // (typeof(arg) === 'object' || %_ClassOf(arg) == 'RegExp')
3429 VirtualFrame::SpilledScope spilled_scope; 3451 VirtualFrame::SpilledScope spilled_scope;
3430 ASSERT(args->length() == 1); 3452 ASSERT(args->length() == 1);
3431 LoadAndSpill(args->at(0)); 3453 LoadAndSpill(args->at(0));
3432 frame_->EmitPop(r1); 3454 frame_->EmitPop(r1);
3433 __ tst(r1, Operand(kSmiTagMask)); 3455 __ tst(r1, Operand(kSmiTagMask));
3434 false_target()->Branch(eq); 3456 false_target()->Branch(eq);
3435 3457
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
3588 Load(args->at(0)); 3610 Load(args->at(0));
3589 Load(args->at(1)); 3611 Load(args->at(1));
3590 Load(args->at(2)); 3612 Load(args->at(2));
3591 Load(args->at(3)); 3613 Load(args->at(3));
3592 3614
3593 frame_->CallRuntime(Runtime::kRegExpExec, 4); 3615 frame_->CallRuntime(Runtime::kRegExpExec, 4);
3594 frame_->EmitPush(r0); 3616 frame_->EmitPush(r0);
3595 } 3617 }
3596 3618
3597 3619
3620 void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) {
3621 ASSERT_EQ(args->length(), 1);
3622
3623 // Load the argument on the stack and jump to the runtime.
3624 Load(args->at(0));
3625
3626 frame_->CallRuntime(Runtime::kNumberToString, 1);
3627 frame_->EmitPush(r0);
3628 }
3629
3630
3631 void CodeGenerator::GenerateMathSin(ZoneList<Expression*>* args) {
3632 ASSERT_EQ(args->length(), 1);
3633 // Load the argument on the stack and jump to the runtime.
3634 Load(args->at(0));
3635 frame_->CallRuntime(Runtime::kMath_sin, 1);
3636 frame_->EmitPush(r0);
3637 }
3638
3639
3640 void CodeGenerator::GenerateMathCos(ZoneList<Expression*>* args) {
3641 ASSERT_EQ(args->length(), 1);
3642 // Load the argument on the stack and jump to the runtime.
3643 Load(args->at(0));
3644 frame_->CallRuntime(Runtime::kMath_cos, 1);
3645 frame_->EmitPush(r0);
3646 }
3647
3648
3598 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) { 3649 void CodeGenerator::GenerateObjectEquals(ZoneList<Expression*>* args) {
3599 VirtualFrame::SpilledScope spilled_scope; 3650 VirtualFrame::SpilledScope spilled_scope;
3600 ASSERT(args->length() == 2); 3651 ASSERT(args->length() == 2);
3601 3652
3602 // Load the two objects into registers and perform the comparison. 3653 // Load the two objects into registers and perform the comparison.
3603 LoadAndSpill(args->at(0)); 3654 LoadAndSpill(args->at(0));
3604 LoadAndSpill(args->at(1)); 3655 LoadAndSpill(args->at(1));
3605 frame_->EmitPop(r0); 3656 frame_->EmitPop(r0);
3606 frame_->EmitPop(r1); 3657 frame_->EmitPop(r1);
3607 __ cmp(r0, Operand(r1)); 3658 __ cmp(r0, Operand(r1));
(...skipping 11 matching lines...) Expand all
3619 (!has_cc() && frame_->height() == original_height + 1)); 3670 (!has_cc() && frame_->height() == original_height + 1));
3620 return; 3671 return;
3621 } 3672 }
3622 3673
3623 ZoneList<Expression*>* args = node->arguments(); 3674 ZoneList<Expression*>* args = node->arguments();
3624 Comment cmnt(masm_, "[ CallRuntime"); 3675 Comment cmnt(masm_, "[ CallRuntime");
3625 Runtime::Function* function = node->function(); 3676 Runtime::Function* function = node->function();
3626 3677
3627 if (function == NULL) { 3678 if (function == NULL) {
3628 // Prepare stack for calling JS runtime function. 3679 // Prepare stack for calling JS runtime function.
3629 __ mov(r0, Operand(node->name()));
3630 frame_->EmitPush(r0);
3631 // Push the builtins object found in the current global object. 3680 // Push the builtins object found in the current global object.
3632 __ ldr(r1, GlobalObject()); 3681 __ ldr(r1, GlobalObject());
3633 __ ldr(r0, FieldMemOperand(r1, GlobalObject::kBuiltinsOffset)); 3682 __ ldr(r0, FieldMemOperand(r1, GlobalObject::kBuiltinsOffset));
3634 frame_->EmitPush(r0); 3683 frame_->EmitPush(r0);
3635 } 3684 }
3636 3685
3637 // Push the arguments ("left-to-right"). 3686 // Push the arguments ("left-to-right").
3638 int arg_count = args->length(); 3687 int arg_count = args->length();
3639 for (int i = 0; i < arg_count; i++) { 3688 for (int i = 0; i < arg_count; i++) {
3640 LoadAndSpill(args->at(i)); 3689 LoadAndSpill(args->at(i));
3641 } 3690 }
3642 3691
3643 if (function == NULL) { 3692 if (function == NULL) {
3644 // Call the JS runtime function. 3693 // Call the JS runtime function.
3694 __ mov(r2, Operand(node->name()));
3645 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP; 3695 InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
3646 Handle<Code> stub = ComputeCallInitialize(arg_count, in_loop); 3696 Handle<Code> stub = ComputeCallInitialize(arg_count, in_loop);
3647 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET, arg_count + 1); 3697 frame_->CallCodeObject(stub, RelocInfo::CODE_TARGET, arg_count + 1);
3648 __ ldr(cp, frame_->Context()); 3698 __ ldr(cp, frame_->Context());
3649 frame_->Drop();
3650 frame_->EmitPush(r0); 3699 frame_->EmitPush(r0);
3651 } else { 3700 } else {
3652 // Call the C runtime function. 3701 // Call the C runtime function.
3653 frame_->CallRuntime(function, arg_count); 3702 frame_->CallRuntime(function, arg_count);
3654 frame_->EmitPush(r0); 3703 frame_->EmitPush(r0);
3655 } 3704 }
3656 ASSERT(frame_->height() == original_height + 1); 3705 ASSERT(frame_->height() == original_height + 1);
3657 } 3706 }
3658 3707
3659 3708
(...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after
4382 break; 4431 break;
4383 } 4432 }
4384 4433
4385 case NAMED: { 4434 case NAMED: {
4386 Comment cmnt(masm, "[ Store to named Property"); 4435 Comment cmnt(masm, "[ Store to named Property");
4387 // Call the appropriate IC code. 4436 // Call the appropriate IC code.
4388 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 4437 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
4389 Handle<String> name(GetName()); 4438 Handle<String> name(GetName());
4390 4439
4391 frame->EmitPop(r0); 4440 frame->EmitPop(r0);
4392 // Setup the name register. 4441 frame->EmitPop(r1);
4393 __ mov(r2, Operand(name)); 4442 __ mov(r2, Operand(name));
4394 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0); 4443 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
4395 frame->EmitPush(r0); 4444 frame->EmitPush(r0);
4396 cgen_->UnloadReference(this); 4445 set_unloaded();
4397 break; 4446 break;
4398 } 4447 }
4399 4448
4400 case KEYED: { 4449 case KEYED: {
4401 Comment cmnt(masm, "[ Store to keyed Property"); 4450 Comment cmnt(masm, "[ Store to keyed Property");
4402 Property* property = expression_->AsProperty(); 4451 Property* property = expression_->AsProperty();
4403 ASSERT(property != NULL); 4452 ASSERT(property != NULL);
4404 cgen_->CodeForSourcePosition(property->position()); 4453 cgen_->CodeForSourcePosition(property->position());
4405 4454
4406 // Call IC code. 4455 // Call IC code.
4407 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 4456 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
4408 // TODO(1222589): Make the IC grab the values from the stack.
4409 frame->EmitPop(r0); // value 4457 frame->EmitPop(r0); // value
4410 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0); 4458 frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
4411 frame->EmitPush(r0); 4459 frame->EmitPush(r0);
4412 cgen_->UnloadReference(this); 4460 cgen_->UnloadReference(this);
4413 break; 4461 break;
4414 } 4462 }
4415 4463
4416 default: 4464 default:
4417 UNREACHABLE(); 4465 UNREACHABLE();
4418 } 4466 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
4473 4521
4474 // Attempt to allocate the context in new space. 4522 // Attempt to allocate the context in new space.
4475 __ AllocateInNewSpace(length + (FixedArray::kHeaderSize / kPointerSize), 4523 __ AllocateInNewSpace(length + (FixedArray::kHeaderSize / kPointerSize),
4476 r0, 4524 r0,
4477 r1, 4525 r1,
4478 r2, 4526 r2,
4479 &gc, 4527 &gc,
4480 TAG_OBJECT); 4528 TAG_OBJECT);
4481 4529
4482 // Load the function from the stack. 4530 // Load the function from the stack.
4483 __ ldr(r3, MemOperand(sp, 0 * kPointerSize)); 4531 __ ldr(r3, MemOperand(sp, 0));
4484 4532
4485 // Setup the object header. 4533 // Setup the object header.
4486 __ LoadRoot(r2, Heap::kContextMapRootIndex); 4534 __ LoadRoot(r2, Heap::kContextMapRootIndex);
4487 __ str(r2, FieldMemOperand(r0, HeapObject::kMapOffset)); 4535 __ str(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
4488 __ mov(r2, Operand(length)); 4536 __ mov(r2, Operand(length));
4489 __ str(r2, FieldMemOperand(r0, Array::kLengthOffset)); 4537 __ str(r2, FieldMemOperand(r0, Array::kLengthOffset));
4490 4538
4491 // Setup the fixed slots. 4539 // Setup the fixed slots.
4492 __ mov(r1, Operand(Smi::FromInt(0))); 4540 __ mov(r1, Operand(Smi::FromInt(0)));
4493 __ str(r3, MemOperand(r0, Context::SlotOffset(Context::CLOSURE_INDEX))); 4541 __ str(r3, MemOperand(r0, Context::SlotOffset(Context::CLOSURE_INDEX)));
(...skipping 15 matching lines...) Expand all
4509 __ mov(cp, r0); 4557 __ mov(cp, r0);
4510 __ pop(); 4558 __ pop();
4511 __ Ret(); 4559 __ Ret();
4512 4560
4513 // Need to collect. Call into runtime system. 4561 // Need to collect. Call into runtime system.
4514 __ bind(&gc); 4562 __ bind(&gc);
4515 __ TailCallRuntime(ExternalReference(Runtime::kNewContext), 1, 1); 4563 __ TailCallRuntime(ExternalReference(Runtime::kNewContext), 1, 1);
4516 } 4564 }
4517 4565
4518 4566
4567 void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) {
4568 // Stack layout on entry:
4569 //
4570 // [sp]: constant elements.
4571 // [sp + kPointerSize]: literal index.
4572 // [sp + (2 * kPointerSize)]: literals array.
4573
4574 // All sizes here are multiples of kPointerSize.
4575 int elements_size = (length_ > 0) ? FixedArray::SizeFor(length_) : 0;
4576 int size = JSArray::kSize + elements_size;
4577
4578 // Load boilerplate object into r3 and check if we need to create a
4579 // boilerplate.
4580 Label slow_case;
4581 __ ldr(r3, MemOperand(sp, 2 * kPointerSize));
4582 __ ldr(r0, MemOperand(sp, 1 * kPointerSize));
4583 __ add(r3, r3, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
4584 __ ldr(r3, MemOperand(r3, r0, LSL, kPointerSizeLog2 - kSmiTagSize));
4585 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
4586 __ cmp(r3, ip);
4587 __ b(eq, &slow_case);
4588
4589 // Allocate both the JS array and the elements array in one big
4590 // allocation. This avoids multiple limit checks.
4591 __ AllocateInNewSpace(size / kPointerSize,
4592 r0,
4593 r1,
4594 r2,
4595 &slow_case,
4596 TAG_OBJECT);
4597
4598 // Copy the JS array part.
4599 for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
4600 if ((i != JSArray::kElementsOffset) || (length_ == 0)) {
4601 __ ldr(r1, FieldMemOperand(r3, i));
4602 __ str(r1, FieldMemOperand(r0, i));
4603 }
4604 }
4605
4606 if (length_ > 0) {
4607 // Get hold of the elements array of the boilerplate and setup the
4608 // elements pointer in the resulting object.
4609 __ ldr(r3, FieldMemOperand(r3, JSArray::kElementsOffset));
4610 __ add(r2, r0, Operand(JSArray::kSize));
4611 __ str(r2, FieldMemOperand(r0, JSArray::kElementsOffset));
4612
4613 // Copy the elements array.
4614 for (int i = 0; i < elements_size; i += kPointerSize) {
4615 __ ldr(r1, FieldMemOperand(r3, i));
4616 __ str(r1, FieldMemOperand(r2, i));
4617 }
4618 }
4619
4620 // Return and remove the on-stack parameters.
4621 __ add(sp, sp, Operand(3 * kPointerSize));
4622 __ Ret();
4623
4624 __ bind(&slow_case);
4625 ExternalReference runtime(Runtime::kCreateArrayLiteralShallow);
4626 __ TailCallRuntime(runtime, 3, 1);
4627 }
4628
4629
4519 // Count leading zeros in a 32 bit word. On ARM5 and later it uses the clz 4630 // Count leading zeros in a 32 bit word. On ARM5 and later it uses the clz
4520 // instruction. On pre-ARM5 hardware this routine gives the wrong answer for 0 4631 // instruction. On pre-ARM5 hardware this routine gives the wrong answer for 0
4521 // (31 instead of 32). 4632 // (31 instead of 32).
4522 static void CountLeadingZeros( 4633 static void CountLeadingZeros(
4523 MacroAssembler* masm, 4634 MacroAssembler* masm,
4524 Register source, 4635 Register source,
4525 Register scratch, 4636 Register scratch,
4526 Register zeros) { 4637 Register zeros) {
4527 #ifdef CAN_USE_ARMV5_INSTRUCTIONS 4638 #ifdef CAN_USE_ARMV5_INSTRUCTIONS
4528 __ clz(zeros, source); // This instruction is only supported after ARM5. 4639 __ clz(zeros, source); // This instruction is only supported after ARM5.
(...skipping 2048 matching lines...) Expand 10 before | Expand all | Expand 10 after
6577 __ ldr(r0, MemOperand(sp, 1 * kPointerSize)); 6688 __ ldr(r0, MemOperand(sp, 1 * kPointerSize));
6578 __ BranchOnSmi(r0, &slow); 6689 __ BranchOnSmi(r0, &slow);
6579 6690
6580 // Check that the left hand is a JS object and put map in r3. 6691 // Check that the left hand is a JS object and put map in r3.
6581 __ CompareObjectType(r0, r3, r2, FIRST_JS_OBJECT_TYPE); 6692 __ CompareObjectType(r0, r3, r2, FIRST_JS_OBJECT_TYPE);
6582 __ b(lt, &slow); 6693 __ b(lt, &slow);
6583 __ cmp(r2, Operand(LAST_JS_OBJECT_TYPE)); 6694 __ cmp(r2, Operand(LAST_JS_OBJECT_TYPE));
6584 __ b(gt, &slow); 6695 __ b(gt, &slow);
6585 6696
6586 // Get the prototype of the function (r4 is result, r2 is scratch). 6697 // Get the prototype of the function (r4 is result, r2 is scratch).
6587 __ ldr(r1, MemOperand(sp, 0 * kPointerSize)); 6698 __ ldr(r1, MemOperand(sp, 0));
6588 __ TryGetFunctionPrototype(r1, r4, r2, &slow); 6699 __ TryGetFunctionPrototype(r1, r4, r2, &slow);
6589 6700
6590 // Check that the function prototype is a JS object. 6701 // Check that the function prototype is a JS object.
6591 __ BranchOnSmi(r4, &slow); 6702 __ BranchOnSmi(r4, &slow);
6592 __ CompareObjectType(r4, r5, r5, FIRST_JS_OBJECT_TYPE); 6703 __ CompareObjectType(r4, r5, r5, FIRST_JS_OBJECT_TYPE);
6593 __ b(lt, &slow); 6704 __ b(lt, &slow);
6594 __ cmp(r5, Operand(LAST_JS_OBJECT_TYPE)); 6705 __ cmp(r5, Operand(LAST_JS_OBJECT_TYPE));
6595 __ b(gt, &slow); 6706 __ b(gt, &slow);
6596 6707
6597 // Register mapping: r3 is object map and r4 is function prototype. 6708 // Register mapping: r3 is object map and r4 is function prototype.
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
6692 6803
6693 // Slow-case: Handle non-smi or out-of-bounds access to arguments 6804 // Slow-case: Handle non-smi or out-of-bounds access to arguments
6694 // by calling the runtime system. 6805 // by calling the runtime system.
6695 __ bind(&slow); 6806 __ bind(&slow);
6696 __ push(r1); 6807 __ push(r1);
6697 __ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1, 1); 6808 __ TailCallRuntime(ExternalReference(Runtime::kGetArgumentsProperty), 1, 1);
6698 } 6809 }
6699 6810
6700 6811
6701 void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) { 6812 void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) {
6813 // sp[0] : number of parameters
6814 // sp[4] : receiver displacement
6815 // sp[8] : function
6816
6702 // Check if the calling frame is an arguments adaptor frame. 6817 // Check if the calling frame is an arguments adaptor frame.
6703 Label runtime; 6818 Label adaptor_frame, try_allocate, runtime;
6704 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); 6819 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
6705 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset)); 6820 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset));
6706 __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 6821 __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
6707 __ b(ne, &runtime); 6822 __ b(eq, &adaptor_frame);
6823
6824 // Get the length from the frame.
6825 __ ldr(r1, MemOperand(sp, 0));
6826 __ b(&try_allocate);
6708 6827
6709 // Patch the arguments.length and the parameters pointer. 6828 // Patch the arguments.length and the parameters pointer.
6710 __ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset)); 6829 __ bind(&adaptor_frame);
6711 __ str(r0, MemOperand(sp, 0 * kPointerSize)); 6830 __ ldr(r1, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset));
6712 __ add(r3, r2, Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); 6831 __ str(r1, MemOperand(sp, 0));
6832 __ add(r3, r2, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize));
6713 __ add(r3, r3, Operand(StandardFrameConstants::kCallerSPOffset)); 6833 __ add(r3, r3, Operand(StandardFrameConstants::kCallerSPOffset));
6714 __ str(r3, MemOperand(sp, 1 * kPointerSize)); 6834 __ str(r3, MemOperand(sp, 1 * kPointerSize));
6715 6835
6836 // Try the new space allocation. Start out with computing the size
6837 // of the arguments object and the elements array (in words, not
6838 // bytes because AllocateInNewSpace expects words).
6839 Label add_arguments_object;
6840 __ bind(&try_allocate);
6841 __ cmp(r1, Operand(0));
6842 __ b(eq, &add_arguments_object);
6843 __ mov(r1, Operand(r1, LSR, kSmiTagSize));
6844 __ add(r1, r1, Operand(FixedArray::kHeaderSize / kPointerSize));
6845 __ bind(&add_arguments_object);
6846 __ add(r1, r1, Operand(Heap::kArgumentsObjectSize / kPointerSize));
6847
6848 // Do the allocation of both objects in one go.
6849 __ AllocateInNewSpace(r1, r0, r2, r3, &runtime, TAG_OBJECT);
6850
6851 // Get the arguments boilerplate from the current (global) context.
6852 int offset = Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX);
6853 __ ldr(r4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
6854 __ ldr(r4, FieldMemOperand(r4, GlobalObject::kGlobalContextOffset));
6855 __ ldr(r4, MemOperand(r4, offset));
6856
6857 // Copy the JS object part.
6858 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) {
6859 __ ldr(r3, FieldMemOperand(r4, i));
6860 __ str(r3, FieldMemOperand(r0, i));
6861 }
6862
6863 // Setup the callee in-object property.
6864 ASSERT(Heap::arguments_callee_index == 0);
6865 __ ldr(r3, MemOperand(sp, 2 * kPointerSize));
6866 __ str(r3, FieldMemOperand(r0, JSObject::kHeaderSize));
6867
6868 // Get the length (smi tagged) and set that as an in-object property too.
6869 ASSERT(Heap::arguments_length_index == 1);
6870 __ ldr(r1, MemOperand(sp, 0 * kPointerSize));
6871 __ str(r1, FieldMemOperand(r0, JSObject::kHeaderSize + kPointerSize));
6872
6873 // If there are no actual arguments, we're done.
6874 Label done;
6875 __ cmp(r1, Operand(0));
6876 __ b(eq, &done);
6877
6878 // Get the parameters pointer from the stack and untag the length.
6879 __ ldr(r2, MemOperand(sp, 1 * kPointerSize));
6880 __ mov(r1, Operand(r1, LSR, kSmiTagSize));
6881
6882 // Setup the elements pointer in the allocated arguments object and
6883 // initialize the header in the elements fixed array.
6884 __ add(r4, r0, Operand(Heap::kArgumentsObjectSize));
6885 __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset));
6886 __ LoadRoot(r3, Heap::kFixedArrayMapRootIndex);
6887 __ str(r3, FieldMemOperand(r4, FixedArray::kMapOffset));
6888 __ str(r1, FieldMemOperand(r4, FixedArray::kLengthOffset));
6889
6890 // Copy the fixed array slots.
6891 Label loop;
6892 // Setup r4 to point to the first array slot.
6893 __ add(r4, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
6894 __ bind(&loop);
6895 // Pre-decrement r2 with kPointerSize on each iteration.
6896 // Pre-decrement in order to skip receiver.
6897 __ ldr(r3, MemOperand(r2, kPointerSize, NegPreIndex));
6898 // Post-increment r4 with kPointerSize on each iteration.
6899 __ str(r3, MemOperand(r4, kPointerSize, PostIndex));
6900 __ sub(r1, r1, Operand(1));
6901 __ cmp(r1, Operand(0));
6902 __ b(ne, &loop);
6903
6904 // Return and remove the on-stack parameters.
6905 __ bind(&done);
6906 __ add(sp, sp, Operand(3 * kPointerSize));
6907 __ Ret();
6908
6716 // Do the runtime call to allocate the arguments object. 6909 // Do the runtime call to allocate the arguments object.
6717 __ bind(&runtime); 6910 __ bind(&runtime);
6718 __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1); 6911 __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3, 1);
6719 } 6912 }
6720 6913
6721 6914
6722 void CallFunctionStub::Generate(MacroAssembler* masm) { 6915 void CallFunctionStub::Generate(MacroAssembler* masm) {
6723 Label slow; 6916 Label slow;
6724 6917
6725 // If the receiver might be a value (string, number or boolean) check for this 6918 // If the receiver might be a value (string, number or boolean) check for this
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
6759 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); 6952 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE);
6760 __ b(ne, &slow); 6953 __ b(ne, &slow);
6761 6954
6762 // Fast-case: Invoke the function now. 6955 // Fast-case: Invoke the function now.
6763 // r1: pushed function 6956 // r1: pushed function
6764 ParameterCount actual(argc_); 6957 ParameterCount actual(argc_);
6765 __ InvokeFunction(r1, actual, JUMP_FUNCTION); 6958 __ InvokeFunction(r1, actual, JUMP_FUNCTION);
6766 6959
6767 // Slow-case: Non-function called. 6960 // Slow-case: Non-function called.
6768 __ bind(&slow); 6961 __ bind(&slow);
6962 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
6963 // of the original receiver from the call site).
6964 __ str(r1, MemOperand(sp, argc_ * kPointerSize));
6769 __ mov(r0, Operand(argc_)); // Setup the number of arguments. 6965 __ mov(r0, Operand(argc_)); // Setup the number of arguments.
6770 __ mov(r2, Operand(0)); 6966 __ mov(r2, Operand(0));
6771 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); 6967 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
6772 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), 6968 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)),
6773 RelocInfo::CODE_TARGET); 6969 RelocInfo::CODE_TARGET);
6774 } 6970 }
6775 6971
6776 6972
6777 const char* CompareStub::GetName() { 6973 const char* CompareStub::GetName() {
6778 switch (cc_) { 6974 switch (cc_) {
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after
7461 7657
7462 // Just jump to runtime to add the two strings. 7658 // Just jump to runtime to add the two strings.
7463 __ bind(&string_add_runtime); 7659 __ bind(&string_add_runtime);
7464 __ TailCallRuntime(ExternalReference(Runtime::kStringAdd), 2, 1); 7660 __ TailCallRuntime(ExternalReference(Runtime::kStringAdd), 2, 1);
7465 } 7661 }
7466 7662
7467 7663
7468 #undef __ 7664 #undef __
7469 7665
7470 } } // namespace v8::internal 7666 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/codegen-arm.h ('k') | src/arm/debug-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698