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

Side by Side Diff: src/arm/code-stubs-arm.cc

Issue 181453002: Reset trunk to 3.24.35.4 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 6 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/OWNERS ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 descriptor->register_param_count_ = 4; 98 descriptor->register_param_count_ = 4;
99 descriptor->register_params_ = registers; 99 descriptor->register_params_ = registers;
100 descriptor->deoptimization_handler_ = 100 descriptor->deoptimization_handler_ =
101 Runtime::FunctionForId(Runtime::kCreateObjectLiteral)->entry; 101 Runtime::FunctionForId(Runtime::kCreateObjectLiteral)->entry;
102 } 102 }
103 103
104 104
105 void CreateAllocationSiteStub::InitializeInterfaceDescriptor( 105 void CreateAllocationSiteStub::InitializeInterfaceDescriptor(
106 Isolate* isolate, 106 Isolate* isolate,
107 CodeStubInterfaceDescriptor* descriptor) { 107 CodeStubInterfaceDescriptor* descriptor) {
108 static Register registers[] = { r2, r3 }; 108 static Register registers[] = { r2 };
109 descriptor->register_param_count_ = 2; 109 descriptor->register_param_count_ = 1;
110 descriptor->register_params_ = registers; 110 descriptor->register_params_ = registers;
111 descriptor->deoptimization_handler_ = NULL; 111 descriptor->deoptimization_handler_ = NULL;
112 } 112 }
113 113
114 114
115 void KeyedLoadFastElementStub::InitializeInterfaceDescriptor( 115 void KeyedLoadFastElementStub::InitializeInterfaceDescriptor(
116 Isolate* isolate, 116 Isolate* isolate,
117 CodeStubInterfaceDescriptor* descriptor) { 117 CodeStubInterfaceDescriptor* descriptor) {
118 static Register registers[] = { r1, r0 }; 118 static Register registers[] = { r1, r0 };
119 descriptor->register_param_count_ = 2; 119 descriptor->register_param_count_ = 2;
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 exponent, 595 exponent,
596 Operand(source_, LSR, 32 - HeapNumber::kMantissaBitsInTopWord)); 596 Operand(source_, LSR, 32 - HeapNumber::kMantissaBitsInTopWord));
597 __ Ret(); 597 __ Ret();
598 } 598 }
599 599
600 600
601 void DoubleToIStub::Generate(MacroAssembler* masm) { 601 void DoubleToIStub::Generate(MacroAssembler* masm) {
602 Label out_of_range, only_low, negate, done; 602 Label out_of_range, only_low, negate, done;
603 Register input_reg = source(); 603 Register input_reg = source();
604 Register result_reg = destination(); 604 Register result_reg = destination();
605 ASSERT(is_truncating());
606 605
607 int double_offset = offset(); 606 int double_offset = offset();
608 // Account for saved regs if input is sp. 607 // Account for saved regs if input is sp.
609 if (input_reg.is(sp)) double_offset += 3 * kPointerSize; 608 if (input_reg.is(sp)) double_offset += 3 * kPointerSize;
610 609
611 Register scratch = GetRegisterThatIsNotOneOf(input_reg, result_reg); 610 Register scratch = GetRegisterThatIsNotOneOf(input_reg, result_reg);
612 Register scratch_low = 611 Register scratch_low =
613 GetRegisterThatIsNotOneOf(input_reg, result_reg, scratch); 612 GetRegisterThatIsNotOneOf(input_reg, result_reg, scratch);
614 Register scratch_high = 613 Register scratch_high =
615 GetRegisterThatIsNotOneOf(input_reg, result_reg, scratch, scratch_low); 614 GetRegisterThatIsNotOneOf(input_reg, result_reg, scratch, scratch_low);
(...skipping 2382 matching lines...) Expand 10 before | Expand all | Expand 10 after
2998 // Load offset into r9 and replace subject string with parent. 2997 // Load offset into r9 and replace subject string with parent.
2999 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset)); 2998 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset));
3000 __ SmiUntag(r9); 2999 __ SmiUntag(r9);
3001 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); 3000 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset));
3002 __ jmp(&check_underlying); // Go to (4). 3001 __ jmp(&check_underlying); // Go to (4).
3003 #endif // V8_INTERPRETED_REGEXP 3002 #endif // V8_INTERPRETED_REGEXP
3004 } 3003 }
3005 3004
3006 3005
3007 static void GenerateRecordCallTarget(MacroAssembler* masm) { 3006 static void GenerateRecordCallTarget(MacroAssembler* masm) {
3008 // Cache the called function in a feedback vector slot. Cache states 3007 // Cache the called function in a global property cell. Cache states
3009 // are uninitialized, monomorphic (indicated by a JSFunction), and 3008 // are uninitialized, monomorphic (indicated by a JSFunction), and
3010 // megamorphic. 3009 // megamorphic.
3011 // r0 : number of arguments to the construct function 3010 // r0 : number of arguments to the construct function
3012 // r1 : the function to call 3011 // r1 : the function to call
3013 // r2 : Feedback vector 3012 // r2 : cache cell for call target
3014 // r3 : slot in feedback vector (Smi)
3015 Label initialize, done, miss, megamorphic, not_array_function; 3013 Label initialize, done, miss, megamorphic, not_array_function;
3016 3014
3017 ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()), 3015 ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()),
3018 masm->isolate()->heap()->undefined_value()); 3016 masm->isolate()->heap()->undefined_value());
3019 ASSERT_EQ(*TypeFeedbackInfo::UninitializedSentinel(masm->isolate()), 3017 ASSERT_EQ(*TypeFeedbackCells::UninitializedSentinel(masm->isolate()),
3020 masm->isolate()->heap()->the_hole_value()); 3018 masm->isolate()->heap()->the_hole_value());
3021 3019
3022 // Load the cache state into r4. 3020 // Load the cache state into r3.
3023 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); 3021 __ ldr(r3, FieldMemOperand(r2, Cell::kValueOffset));
3024 __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize));
3025 3022
3026 // A monomorphic cache hit or an already megamorphic state: invoke the 3023 // A monomorphic cache hit or an already megamorphic state: invoke the
3027 // function without changing the state. 3024 // function without changing the state.
3028 __ cmp(r4, r1); 3025 __ cmp(r3, r1);
3029 __ b(eq, &done); 3026 __ b(eq, &done);
3030 3027
3031 // If we came here, we need to see if we are the array function. 3028 // If we came here, we need to see if we are the array function.
3032 // If we didn't have a matching function, and we didn't find the megamorph 3029 // If we didn't have a matching function, and we didn't find the megamorph
3033 // sentinel, then we have in the slot either some other function or an 3030 // sentinel, then we have in the cell either some other function or an
3034 // AllocationSite. Do a map check on the object in ecx. 3031 // AllocationSite. Do a map check on the object in ecx.
3035 __ ldr(r5, FieldMemOperand(r4, 0)); 3032 __ ldr(r5, FieldMemOperand(r3, 0));
3036 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex); 3033 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex);
3037 __ b(ne, &miss); 3034 __ b(ne, &miss);
3038 3035
3039 // Make sure the function is the Array() function 3036 // Make sure the function is the Array() function
3040 __ LoadArrayFunction(r4); 3037 __ LoadArrayFunction(r3);
3041 __ cmp(r1, r4); 3038 __ cmp(r1, r3);
3042 __ b(ne, &megamorphic); 3039 __ b(ne, &megamorphic);
3043 __ jmp(&done); 3040 __ jmp(&done);
3044 3041
3045 __ bind(&miss); 3042 __ bind(&miss);
3046 3043
3047 // A monomorphic miss (i.e, here the cache is not uninitialized) goes 3044 // A monomorphic miss (i.e, here the cache is not uninitialized) goes
3048 // megamorphic. 3045 // megamorphic.
3049 __ CompareRoot(r4, Heap::kTheHoleValueRootIndex); 3046 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex);
3050 __ b(eq, &initialize); 3047 __ b(eq, &initialize);
3051 // MegamorphicSentinel is an immortal immovable object (undefined) so no 3048 // MegamorphicSentinel is an immortal immovable object (undefined) so no
3052 // write-barrier is needed. 3049 // write-barrier is needed.
3053 __ bind(&megamorphic); 3050 __ bind(&megamorphic);
3054 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
3055 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 3051 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
3056 __ str(ip, FieldMemOperand(r4, FixedArray::kHeaderSize)); 3052 __ str(ip, FieldMemOperand(r2, Cell::kValueOffset));
3057 __ jmp(&done); 3053 __ jmp(&done);
3058 3054
3059 // An uninitialized cache is patched with the function or sentinel to 3055 // An uninitialized cache is patched with the function or sentinel to
3060 // indicate the ElementsKind if function is the Array constructor. 3056 // indicate the ElementsKind if function is the Array constructor.
3061 __ bind(&initialize); 3057 __ bind(&initialize);
3062 // Make sure the function is the Array() function 3058 // Make sure the function is the Array() function
3063 __ LoadArrayFunction(r4); 3059 __ LoadArrayFunction(r3);
3064 __ cmp(r1, r4); 3060 __ cmp(r1, r3);
3065 __ b(ne, &not_array_function); 3061 __ b(ne, &not_array_function);
3066 3062
3067 // The target function is the Array constructor, 3063 // The target function is the Array constructor,
3068 // Create an AllocationSite if we don't already have it, store it in the slot. 3064 // Create an AllocationSite if we don't already have it, store it in the cell
3069 { 3065 {
3070 FrameScope scope(masm, StackFrame::INTERNAL); 3066 FrameScope scope(masm, StackFrame::INTERNAL);
3071 3067
3072 // Arguments register must be smi-tagged to call out. 3068 // Arguments register must be smi-tagged to call out.
3073 __ SmiTag(r0); 3069 __ SmiTag(r0);
3074 __ Push(r3, r2, r1, r0); 3070 __ Push(r2, r1, r0);
3075 3071
3076 CreateAllocationSiteStub create_stub; 3072 CreateAllocationSiteStub create_stub;
3077 __ CallStub(&create_stub); 3073 __ CallStub(&create_stub);
3078 3074
3079 __ Pop(r3, r2, r1, r0); 3075 __ Pop(r2, r1, r0);
3080 __ SmiUntag(r0); 3076 __ SmiUntag(r0);
3081 } 3077 }
3082 __ b(&done); 3078 __ b(&done);
3083 3079
3084 __ bind(&not_array_function); 3080 __ bind(&not_array_function);
3085 3081 __ str(r1, FieldMemOperand(r2, Cell::kValueOffset));
3086 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); 3082 // No need for a write barrier here - cells are rescanned.
3087 __ add(r4, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
3088 __ str(r1, MemOperand(r4, 0));
3089
3090 __ Push(r4, r2, r1);
3091 __ RecordWrite(r2, r4, r1, kLRHasNotBeenSaved, kDontSaveFPRegs,
3092 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
3093 __ Pop(r4, r2, r1);
3094 3083
3095 __ bind(&done); 3084 __ bind(&done);
3096 } 3085 }
3097 3086
3098 3087
3099 void CallFunctionStub::Generate(MacroAssembler* masm) { 3088 void CallFunctionStub::Generate(MacroAssembler* masm) {
3100 // r1 : the function to call 3089 // r1 : the function to call
3101 // r2 : feedback vector 3090 // r2 : cache cell for call target
3102 // r3 : (only if r2 is not undefined) slot in feedback vector (Smi)
3103 Label slow, non_function, wrap, cont; 3091 Label slow, non_function, wrap, cont;
3104 3092
3105 if (NeedsChecks()) { 3093 if (NeedsChecks()) {
3106 // Check that the function is really a JavaScript function. 3094 // Check that the function is really a JavaScript function.
3107 // r1: pushed function (to be verified) 3095 // r1: pushed function (to be verified)
3108 __ JumpIfSmi(r1, &non_function); 3096 __ JumpIfSmi(r1, &non_function);
3109 3097
3110 // Goto slow case if we do not have a function. 3098 // Goto slow case if we do not have a function.
3111 __ CompareObjectType(r1, r4, r4, JS_FUNCTION_TYPE); 3099 __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE);
3112 __ b(ne, &slow); 3100 __ b(ne, &slow);
3113 3101
3114 if (RecordCallTarget()) { 3102 if (RecordCallTarget()) {
3115 GenerateRecordCallTarget(masm); 3103 GenerateRecordCallTarget(masm);
3116 } 3104 }
3117 } 3105 }
3118 3106
3119 // Fast-case: Invoke the function now. 3107 // Fast-case: Invoke the function now.
3120 // r1: pushed function 3108 // r1: pushed function
3121 ParameterCount actual(argc_); 3109 ParameterCount actual(argc_);
(...skipping 27 matching lines...) Expand all
3149 } 3137 }
3150 __ InvokeFunction(r1, actual, JUMP_FUNCTION, NullCallWrapper()); 3138 __ InvokeFunction(r1, actual, JUMP_FUNCTION, NullCallWrapper());
3151 3139
3152 if (NeedsChecks()) { 3140 if (NeedsChecks()) {
3153 // Slow-case: Non-function called. 3141 // Slow-case: Non-function called.
3154 __ bind(&slow); 3142 __ bind(&slow);
3155 if (RecordCallTarget()) { 3143 if (RecordCallTarget()) {
3156 // If there is a call target cache, mark it megamorphic in the 3144 // If there is a call target cache, mark it megamorphic in the
3157 // non-function case. MegamorphicSentinel is an immortal immovable 3145 // non-function case. MegamorphicSentinel is an immortal immovable
3158 // object (undefined) so no write barrier is needed. 3146 // object (undefined) so no write barrier is needed.
3159 ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()), 3147 ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()),
3160 masm->isolate()->heap()->undefined_value()); 3148 masm->isolate()->heap()->undefined_value());
3161 __ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3));
3162 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 3149 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
3163 __ str(ip, FieldMemOperand(r5, FixedArray::kHeaderSize)); 3150 __ str(ip, FieldMemOperand(r2, Cell::kValueOffset));
3164 } 3151 }
3165 // Check for function proxy. 3152 // Check for function proxy.
3166 __ cmp(r4, Operand(JS_FUNCTION_PROXY_TYPE)); 3153 __ cmp(r3, Operand(JS_FUNCTION_PROXY_TYPE));
3167 __ b(ne, &non_function); 3154 __ b(ne, &non_function);
3168 __ push(r1); // put proxy as additional argument 3155 __ push(r1); // put proxy as additional argument
3169 __ mov(r0, Operand(argc_ + 1, RelocInfo::NONE32)); 3156 __ mov(r0, Operand(argc_ + 1, RelocInfo::NONE32));
3170 __ mov(r2, Operand::Zero()); 3157 __ mov(r2, Operand::Zero());
3171 __ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY); 3158 __ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY);
3172 { 3159 {
3173 Handle<Code> adaptor = 3160 Handle<Code> adaptor =
3174 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); 3161 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
3175 __ Jump(adaptor, RelocInfo::CODE_TARGET); 3162 __ Jump(adaptor, RelocInfo::CODE_TARGET);
3176 } 3163 }
(...skipping 19 matching lines...) Expand all
3196 } 3183 }
3197 __ str(r0, MemOperand(sp, argc_ * kPointerSize)); 3184 __ str(r0, MemOperand(sp, argc_ * kPointerSize));
3198 __ jmp(&cont); 3185 __ jmp(&cont);
3199 } 3186 }
3200 } 3187 }
3201 3188
3202 3189
3203 void CallConstructStub::Generate(MacroAssembler* masm) { 3190 void CallConstructStub::Generate(MacroAssembler* masm) {
3204 // r0 : number of arguments 3191 // r0 : number of arguments
3205 // r1 : the function to call 3192 // r1 : the function to call
3206 // r2 : feedback vector 3193 // r2 : cache cell for call target
3207 // r3 : (only if r2 is not undefined) slot in feedback vector (Smi)
3208 Label slow, non_function_call; 3194 Label slow, non_function_call;
3209 3195
3210 // Check that the function is not a smi. 3196 // Check that the function is not a smi.
3211 __ JumpIfSmi(r1, &non_function_call); 3197 __ JumpIfSmi(r1, &non_function_call);
3212 // Check that the function is a JSFunction. 3198 // Check that the function is a JSFunction.
3213 __ CompareObjectType(r1, r4, r4, JS_FUNCTION_TYPE); 3199 __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE);
3214 __ b(ne, &slow); 3200 __ b(ne, &slow);
3215 3201
3216 if (RecordCallTarget()) { 3202 if (RecordCallTarget()) {
3217 GenerateRecordCallTarget(masm); 3203 GenerateRecordCallTarget(masm);
3218 } 3204 }
3219 3205
3220 // Jump to the function-specific construct stub. 3206 // Jump to the function-specific construct stub.
3221 Register jmp_reg = r4; 3207 Register jmp_reg = r3;
3222 __ ldr(jmp_reg, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); 3208 __ ldr(jmp_reg, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
3223 __ ldr(jmp_reg, FieldMemOperand(jmp_reg, 3209 __ ldr(jmp_reg, FieldMemOperand(jmp_reg,
3224 SharedFunctionInfo::kConstructStubOffset)); 3210 SharedFunctionInfo::kConstructStubOffset));
3225 __ add(pc, jmp_reg, Operand(Code::kHeaderSize - kHeapObjectTag)); 3211 __ add(pc, jmp_reg, Operand(Code::kHeaderSize - kHeapObjectTag));
3226 3212
3227 // r0: number of arguments 3213 // r0: number of arguments
3228 // r1: called object 3214 // r1: called object
3229 // r4: object type 3215 // r3: object type
3230 Label do_call; 3216 Label do_call;
3231 __ bind(&slow); 3217 __ bind(&slow);
3232 __ cmp(r4, Operand(JS_FUNCTION_PROXY_TYPE)); 3218 __ cmp(r3, Operand(JS_FUNCTION_PROXY_TYPE));
3233 __ b(ne, &non_function_call); 3219 __ b(ne, &non_function_call);
3234 __ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR); 3220 __ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
3235 __ jmp(&do_call); 3221 __ jmp(&do_call);
3236 3222
3237 __ bind(&non_function_call); 3223 __ bind(&non_function_call);
3238 __ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); 3224 __ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
3239 __ bind(&do_call); 3225 __ bind(&do_call);
3240 // Set expected number of arguments to zero (not changing r0). 3226 // Set expected number of arguments to zero (not changing r0).
3241 __ mov(r2, Operand::Zero()); 3227 __ mov(r2, Operand::Zero());
3242 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 3228 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
(...skipping 1939 matching lines...) Expand 10 before | Expand all | Expand 10 after
5182 ArraySingleArgumentConstructorStub stub_holey(holey_initial, 5168 ArraySingleArgumentConstructorStub stub_holey(holey_initial,
5183 DISABLE_ALLOCATION_SITES); 5169 DISABLE_ALLOCATION_SITES);
5184 __ TailCallStub(&stub_holey); 5170 __ TailCallStub(&stub_holey);
5185 5171
5186 __ bind(&normal_sequence); 5172 __ bind(&normal_sequence);
5187 ArraySingleArgumentConstructorStub stub(initial, 5173 ArraySingleArgumentConstructorStub stub(initial,
5188 DISABLE_ALLOCATION_SITES); 5174 DISABLE_ALLOCATION_SITES);
5189 __ TailCallStub(&stub); 5175 __ TailCallStub(&stub);
5190 } else if (mode == DONT_OVERRIDE) { 5176 } else if (mode == DONT_OVERRIDE) {
5191 // We are going to create a holey array, but our kind is non-holey. 5177 // We are going to create a holey array, but our kind is non-holey.
5192 // Fix kind and retry (only if we have an allocation site in the slot). 5178 // Fix kind and retry (only if we have an allocation site in the cell).
5193 __ add(r3, r3, Operand(1)); 5179 __ add(r3, r3, Operand(1));
5194 5180
5195 if (FLAG_debug_code) { 5181 if (FLAG_debug_code) {
5196 __ ldr(r5, FieldMemOperand(r2, 0)); 5182 __ ldr(r5, FieldMemOperand(r2, 0));
5197 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex); 5183 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex);
5198 __ Assert(eq, kExpectedAllocationSite); 5184 __ Assert(eq, kExpectedAllocationSite);
5199 } 5185 }
5200 5186
5201 // Save the resulting elements kind in type info. We can't just store r3 5187 // Save the resulting elements kind in type info. We can't just store r3
5202 // in the AllocationSite::transition_info field because elements kind is 5188 // in the AllocationSite::transition_info field because elements kind is
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
5290 } else { 5276 } else {
5291 UNREACHABLE(); 5277 UNREACHABLE();
5292 } 5278 }
5293 } 5279 }
5294 5280
5295 5281
5296 void ArrayConstructorStub::Generate(MacroAssembler* masm) { 5282 void ArrayConstructorStub::Generate(MacroAssembler* masm) {
5297 // ----------- S t a t e ------------- 5283 // ----------- S t a t e -------------
5298 // -- r0 : argc (only if argument_count_ == ANY) 5284 // -- r0 : argc (only if argument_count_ == ANY)
5299 // -- r1 : constructor 5285 // -- r1 : constructor
5300 // -- r2 : feedback vector (fixed array or undefined) 5286 // -- r2 : type info cell
5301 // -- r3 : slot index (if r2 is fixed array)
5302 // -- sp[0] : return address 5287 // -- sp[0] : return address
5303 // -- sp[4] : last argument 5288 // -- sp[4] : last argument
5304 // ----------------------------------- 5289 // -----------------------------------
5305 if (FLAG_debug_code) { 5290 if (FLAG_debug_code) {
5306 // The array construct code is only set for the global and natives 5291 // The array construct code is only set for the global and natives
5307 // builtin Array functions which always have maps. 5292 // builtin Array functions which always have maps.
5308 5293
5309 // Initial map for the builtin Array function should be a map. 5294 // Initial map for the builtin Array function should be a map.
5310 __ ldr(r4, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset)); 5295 __ ldr(r3, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset));
5311 // Will both indicate a NULL and a Smi. 5296 // Will both indicate a NULL and a Smi.
5312 __ tst(r4, Operand(kSmiTagMask)); 5297 __ tst(r3, Operand(kSmiTagMask));
5313 __ Assert(ne, kUnexpectedInitialMapForArrayFunction); 5298 __ Assert(ne, kUnexpectedInitialMapForArrayFunction);
5314 __ CompareObjectType(r4, r4, r5, MAP_TYPE); 5299 __ CompareObjectType(r3, r3, r4, MAP_TYPE);
5315 __ Assert(eq, kUnexpectedInitialMapForArrayFunction); 5300 __ Assert(eq, kUnexpectedInitialMapForArrayFunction);
5316 5301
5317 // We should either have undefined in ebx or a valid fixed array. 5302 // We should either have undefined in ebx or a valid cell
5318 Label okay_here; 5303 Label okay_here;
5319 Handle<Map> fixed_array_map = masm->isolate()->factory()->fixed_array_map(); 5304 Handle<Map> cell_map = masm->isolate()->factory()->cell_map();
5320 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); 5305 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex);
5321 __ b(eq, &okay_here); 5306 __ b(eq, &okay_here);
5322 __ ldr(r4, FieldMemOperand(r2, 0)); 5307 __ ldr(r3, FieldMemOperand(r2, 0));
5323 __ cmp(r4, Operand(fixed_array_map)); 5308 __ cmp(r3, Operand(cell_map));
5324 __ Assert(eq, kExpectedFixedArrayInRegisterR2); 5309 __ Assert(eq, kExpectedPropertyCellInRegisterEbx);
5325
5326 // r3 should be a smi if we don't have undefined in r2
5327 __ AssertSmi(r3);
5328
5329 __ bind(&okay_here); 5310 __ bind(&okay_here);
5330 } 5311 }
5331 5312
5332 Label no_info; 5313 Label no_info;
5333 // Get the elements kind and case on that. 5314 // Get the elements kind and case on that.
5334 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); 5315 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex);
5335 __ b(eq, &no_info); 5316 __ b(eq, &no_info);
5336 __ add(r2, r2, Operand::PointerOffsetFromSmiKey(r3)); 5317 __ ldr(r2, FieldMemOperand(r2, Cell::kValueOffset));
5337 __ ldr(r2, FieldMemOperand(r2, FixedArray::kHeaderSize));
5338 5318
5339 // If the feedback vector is undefined, or contains anything other than an 5319 // If the type cell is undefined, or contains anything other than an
5340 // AllocationSite, call an array constructor that doesn't use AllocationSites. 5320 // AllocationSite, call an array constructor that doesn't use AllocationSites.
5341 __ ldr(r4, FieldMemOperand(r2, 0)); 5321 __ ldr(r4, FieldMemOperand(r2, 0));
5342 __ CompareRoot(r4, Heap::kAllocationSiteMapRootIndex); 5322 __ CompareRoot(r4, Heap::kAllocationSiteMapRootIndex);
5343 __ b(ne, &no_info); 5323 __ b(ne, &no_info);
5344 5324
5345 __ ldr(r3, FieldMemOperand(r2, AllocationSite::kTransitionInfoOffset)); 5325 __ ldr(r3, FieldMemOperand(r2, AllocationSite::kTransitionInfoOffset));
5346 __ SmiUntag(r3); 5326 __ SmiUntag(r3);
5347 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0); 5327 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0);
5348 __ and_(r3, r3, Operand(AllocationSite::ElementsKindBits::kMask)); 5328 __ and_(r3, r3, Operand(AllocationSite::ElementsKindBits::kMask));
5349 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); 5329 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
5442 // -- sp[argc * 4] : receiver 5422 // -- sp[argc * 4] : receiver
5443 // ----------------------------------- 5423 // -----------------------------------
5444 5424
5445 Register callee = r0; 5425 Register callee = r0;
5446 Register call_data = r4; 5426 Register call_data = r4;
5447 Register holder = r2; 5427 Register holder = r2;
5448 Register api_function_address = r1; 5428 Register api_function_address = r1;
5449 Register context = cp; 5429 Register context = cp;
5450 5430
5451 int argc = ArgumentBits::decode(bit_field_); 5431 int argc = ArgumentBits::decode(bit_field_);
5452 bool is_store = IsStoreBits::decode(bit_field_); 5432 bool restore_context = RestoreContextBits::decode(bit_field_);
5453 bool call_data_undefined = CallDataUndefinedBits::decode(bit_field_); 5433 bool call_data_undefined = CallDataUndefinedBits::decode(bit_field_);
5454 5434
5455 typedef FunctionCallbackArguments FCA; 5435 typedef FunctionCallbackArguments FCA;
5456 5436
5457 STATIC_ASSERT(FCA::kContextSaveIndex == 6); 5437 STATIC_ASSERT(FCA::kContextSaveIndex == 6);
5458 STATIC_ASSERT(FCA::kCalleeIndex == 5); 5438 STATIC_ASSERT(FCA::kCalleeIndex == 5);
5459 STATIC_ASSERT(FCA::kDataIndex == 4); 5439 STATIC_ASSERT(FCA::kDataIndex == 4);
5460 STATIC_ASSERT(FCA::kReturnValueOffset == 3); 5440 STATIC_ASSERT(FCA::kReturnValueOffset == 3);
5461 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); 5441 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2);
5462 STATIC_ASSERT(FCA::kIsolateIndex == 1); 5442 STATIC_ASSERT(FCA::kIsolateIndex == 1);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
5520 const int kStackUnwindSpace = argc + FCA::kArgsLength + 1; 5500 const int kStackUnwindSpace = argc + FCA::kArgsLength + 1;
5521 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback); 5501 Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
5522 ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL; 5502 ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL;
5523 ApiFunction thunk_fun(thunk_address); 5503 ApiFunction thunk_fun(thunk_address);
5524 ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type, 5504 ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
5525 masm->isolate()); 5505 masm->isolate());
5526 5506
5527 AllowExternalCallThatCantCauseGC scope(masm); 5507 AllowExternalCallThatCantCauseGC scope(masm);
5528 MemOperand context_restore_operand( 5508 MemOperand context_restore_operand(
5529 fp, (2 + FCA::kContextSaveIndex) * kPointerSize); 5509 fp, (2 + FCA::kContextSaveIndex) * kPointerSize);
5530 // Stores return the first js argument 5510 MemOperand return_value_operand(fp,
5531 int return_value_offset = 0; 5511 (2 + FCA::kReturnValueOffset) * kPointerSize);
5532 if (is_store) {
5533 return_value_offset = 2 + FCA::kArgsLength;
5534 } else {
5535 return_value_offset = 2 + FCA::kReturnValueOffset;
5536 }
5537 MemOperand return_value_operand(fp, return_value_offset * kPointerSize);
5538 5512
5539 __ CallApiFunctionAndReturn(api_function_address, 5513 __ CallApiFunctionAndReturn(api_function_address,
5540 thunk_ref, 5514 thunk_ref,
5541 kStackUnwindSpace, 5515 kStackUnwindSpace,
5542 return_value_operand, 5516 return_value_operand,
5543 &context_restore_operand); 5517 restore_context ?
5518 &context_restore_operand : NULL);
5544 } 5519 }
5545 5520
5546 5521
5547 void CallApiGetterStub::Generate(MacroAssembler* masm) { 5522 void CallApiGetterStub::Generate(MacroAssembler* masm) {
5548 // ----------- S t a t e ------------- 5523 // ----------- S t a t e -------------
5549 // -- sp[0] : name 5524 // -- sp[0] : name
5550 // -- sp[4 - kArgsLength*4] : PropertyCallbackArguments object 5525 // -- sp[4 - kArgsLength*4] : PropertyCallbackArguments object
5551 // -- ... 5526 // -- ...
5552 // -- r2 : api_function_address 5527 // -- r2 : api_function_address
5553 // ----------------------------------- 5528 // -----------------------------------
(...skipping 26 matching lines...) Expand all
5580 MemOperand(fp, 6 * kPointerSize), 5555 MemOperand(fp, 6 * kPointerSize),
5581 NULL); 5556 NULL);
5582 } 5557 }
5583 5558
5584 5559
5585 #undef __ 5560 #undef __
5586 5561
5587 } } // namespace v8::internal 5562 } } // namespace v8::internal
5588 5563
5589 #endif // V8_TARGET_ARCH_ARM 5564 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/OWNERS ('k') | src/arm/debug-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698