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

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

Issue 137403009: Adding a type vector to replace type cells. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed feedback. 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 | « no previous file | 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 }; 108 static Register registers[] = { r2, r3 };
109 descriptor->register_param_count_ = 1; 109 descriptor->register_param_count_ = 2;
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 2877 matching lines...) Expand 10 before | Expand all | Expand 10 after
2997 // Load offset into r9 and replace subject string with parent. 2997 // Load offset into r9 and replace subject string with parent.
2998 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset)); 2998 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset));
2999 __ SmiUntag(r9); 2999 __ SmiUntag(r9);
3000 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); 3000 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset));
3001 __ jmp(&check_underlying); // Go to (4). 3001 __ jmp(&check_underlying); // Go to (4).
3002 #endif // V8_INTERPRETED_REGEXP 3002 #endif // V8_INTERPRETED_REGEXP
3003 } 3003 }
3004 3004
3005 3005
3006 static void GenerateRecordCallTarget(MacroAssembler* masm) { 3006 static void GenerateRecordCallTarget(MacroAssembler* masm) {
3007 // Cache the called function in a global property cell. Cache states 3007 // Cache the called function in a feedback vector slot. Cache states
3008 // are uninitialized, monomorphic (indicated by a JSFunction), and 3008 // are uninitialized, monomorphic (indicated by a JSFunction), and
3009 // megamorphic. 3009 // megamorphic.
3010 // r0 : number of arguments to the construct function 3010 // r0 : number of arguments to the construct function
3011 // r1 : the function to call 3011 // r1 : the function to call
3012 // r2 : cache cell for call target 3012 // r2 : Feedback vector
3013 // r3 : slot in feedback vector (Smi)
3013 Label initialize, done, miss, megamorphic, not_array_function; 3014 Label initialize, done, miss, megamorphic, not_array_function;
3014 3015
3015 ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()), 3016 ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()),
3016 masm->isolate()->heap()->undefined_value()); 3017 masm->isolate()->heap()->undefined_value());
3017 ASSERT_EQ(*TypeFeedbackCells::UninitializedSentinel(masm->isolate()), 3018 ASSERT_EQ(*TypeFeedbackInfo::UninitializedSentinel(masm->isolate()),
3018 masm->isolate()->heap()->the_hole_value()); 3019 masm->isolate()->heap()->the_hole_value());
3019 3020
3020 // Load the cache state into r3. 3021 // Load the cache state into r4.
3021 __ ldr(r3, FieldMemOperand(r2, Cell::kValueOffset)); 3022 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
3023 __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize));
3022 3024
3023 // A monomorphic cache hit or an already megamorphic state: invoke the 3025 // A monomorphic cache hit or an already megamorphic state: invoke the
3024 // function without changing the state. 3026 // function without changing the state.
3025 __ cmp(r3, r1); 3027 __ cmp(r4, r1);
3026 __ b(eq, &done); 3028 __ b(eq, &done);
3027 3029
3028 // If we came here, we need to see if we are the array function. 3030 // If we came here, we need to see if we are the array function.
3029 // If we didn't have a matching function, and we didn't find the megamorph 3031 // If we didn't have a matching function, and we didn't find the megamorph
3030 // sentinel, then we have in the cell either some other function or an 3032 // sentinel, then we have in the slot either some other function or an
3031 // AllocationSite. Do a map check on the object in ecx. 3033 // AllocationSite. Do a map check on the object in ecx.
3032 __ ldr(r5, FieldMemOperand(r3, 0)); 3034 __ ldr(r5, FieldMemOperand(r4, 0));
3033 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex); 3035 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex);
3034 __ b(ne, &miss); 3036 __ b(ne, &miss);
3035 3037
3036 // Make sure the function is the Array() function 3038 // Make sure the function is the Array() function
3037 __ LoadArrayFunction(r3); 3039 __ LoadArrayFunction(r4);
3038 __ cmp(r1, r3); 3040 __ cmp(r1, r4);
3039 __ b(ne, &megamorphic); 3041 __ b(ne, &megamorphic);
3040 __ jmp(&done); 3042 __ jmp(&done);
3041 3043
3042 __ bind(&miss); 3044 __ bind(&miss);
3043 3045
3044 // A monomorphic miss (i.e, here the cache is not uninitialized) goes 3046 // A monomorphic miss (i.e, here the cache is not uninitialized) goes
3045 // megamorphic. 3047 // megamorphic.
3046 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); 3048 __ CompareRoot(r4, Heap::kTheHoleValueRootIndex);
3047 __ b(eq, &initialize); 3049 __ b(eq, &initialize);
3048 // MegamorphicSentinel is an immortal immovable object (undefined) so no 3050 // MegamorphicSentinel is an immortal immovable object (undefined) so no
3049 // write-barrier is needed. 3051 // write-barrier is needed.
3050 __ bind(&megamorphic); 3052 __ bind(&megamorphic);
3053 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
3051 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 3054 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
3052 __ str(ip, FieldMemOperand(r2, Cell::kValueOffset)); 3055 __ str(ip, FieldMemOperand(r4, FixedArray::kHeaderSize));
3053 __ jmp(&done); 3056 __ jmp(&done);
3054 3057
3055 // An uninitialized cache is patched with the function or sentinel to 3058 // An uninitialized cache is patched with the function or sentinel to
3056 // indicate the ElementsKind if function is the Array constructor. 3059 // indicate the ElementsKind if function is the Array constructor.
3057 __ bind(&initialize); 3060 __ bind(&initialize);
3058 // Make sure the function is the Array() function 3061 // Make sure the function is the Array() function
3059 __ LoadArrayFunction(r3); 3062 __ LoadArrayFunction(r4);
3060 __ cmp(r1, r3); 3063 __ cmp(r1, r4);
3061 __ b(ne, &not_array_function); 3064 __ b(ne, &not_array_function);
3062 3065
3063 // The target function is the Array constructor, 3066 // The target function is the Array constructor,
3064 // Create an AllocationSite if we don't already have it, store it in the cell 3067 // Create an AllocationSite if we don't already have it, store it in the slot.
3065 { 3068 {
3066 FrameScope scope(masm, StackFrame::INTERNAL); 3069 FrameScope scope(masm, StackFrame::INTERNAL);
3067 3070
3068 // Arguments register must be smi-tagged to call out. 3071 // Arguments register must be smi-tagged to call out.
3069 __ SmiTag(r0); 3072 __ SmiTag(r0);
3070 __ Push(r2, r1, r0); 3073 __ Push(r3, r2, r1, r0);
3071 3074
3072 CreateAllocationSiteStub create_stub; 3075 CreateAllocationSiteStub create_stub;
3073 __ CallStub(&create_stub); 3076 __ CallStub(&create_stub);
3074 3077
3075 __ Pop(r2, r1, r0); 3078 __ Pop(r3, r2, r1, r0);
3076 __ SmiUntag(r0); 3079 __ SmiUntag(r0);
3077 } 3080 }
3078 __ b(&done); 3081 __ b(&done);
3079 3082
3080 __ bind(&not_array_function); 3083 __ bind(&not_array_function);
3081 __ str(r1, FieldMemOperand(r2, Cell::kValueOffset)); 3084
3082 // No need for a write barrier here - cells are rescanned. 3085 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
3086 __ add(r4, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
3087 __ str(r1, MemOperand(r4, 0));
3088
3089 __ Push(r4, r2, r1);
3090 __ RecordWrite(r2, r4, r1, kLRHasNotBeenSaved, kDontSaveFPRegs,
3091 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
3092 __ Pop(r4, r2, r1);
3083 3093
3084 __ bind(&done); 3094 __ bind(&done);
3085 } 3095 }
3086 3096
3087 3097
3088 void CallFunctionStub::Generate(MacroAssembler* masm) { 3098 void CallFunctionStub::Generate(MacroAssembler* masm) {
3089 // r1 : the function to call 3099 // r1 : the function to call
3090 // r2 : cache cell for call target 3100 // r2 : feedback vector
3101 // r3 : (only if r2 is not undefined) slot in feedback vector (Smi)
3091 Label slow, non_function, wrap, cont; 3102 Label slow, non_function, wrap, cont;
3092 3103
3093 if (NeedsChecks()) { 3104 if (NeedsChecks()) {
3094 // Check that the function is really a JavaScript function. 3105 // Check that the function is really a JavaScript function.
3095 // r1: pushed function (to be verified) 3106 // r1: pushed function (to be verified)
3096 __ JumpIfSmi(r1, &non_function); 3107 __ JumpIfSmi(r1, &non_function);
3097 3108
3098 // Goto slow case if we do not have a function. 3109 // Goto slow case if we do not have a function.
3099 __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE); 3110 __ CompareObjectType(r1, r4, r4, JS_FUNCTION_TYPE);
3100 __ b(ne, &slow); 3111 __ b(ne, &slow);
3101 3112
3102 if (RecordCallTarget()) { 3113 if (RecordCallTarget()) {
3103 GenerateRecordCallTarget(masm); 3114 GenerateRecordCallTarget(masm);
3104 } 3115 }
3105 } 3116 }
3106 3117
3107 // Fast-case: Invoke the function now. 3118 // Fast-case: Invoke the function now.
3108 // r1: pushed function 3119 // r1: pushed function
3109 ParameterCount actual(argc_); 3120 ParameterCount actual(argc_);
(...skipping 27 matching lines...) Expand all
3137 } 3148 }
3138 __ InvokeFunction(r1, actual, JUMP_FUNCTION, NullCallWrapper()); 3149 __ InvokeFunction(r1, actual, JUMP_FUNCTION, NullCallWrapper());
3139 3150
3140 if (NeedsChecks()) { 3151 if (NeedsChecks()) {
3141 // Slow-case: Non-function called. 3152 // Slow-case: Non-function called.
3142 __ bind(&slow); 3153 __ bind(&slow);
3143 if (RecordCallTarget()) { 3154 if (RecordCallTarget()) {
3144 // If there is a call target cache, mark it megamorphic in the 3155 // If there is a call target cache, mark it megamorphic in the
3145 // non-function case. MegamorphicSentinel is an immortal immovable 3156 // non-function case. MegamorphicSentinel is an immortal immovable
3146 // object (undefined) so no write barrier is needed. 3157 // object (undefined) so no write barrier is needed.
3147 ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()), 3158 ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()),
3148 masm->isolate()->heap()->undefined_value()); 3159 masm->isolate()->heap()->undefined_value());
3160 __ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3));
3149 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 3161 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
3150 __ str(ip, FieldMemOperand(r2, Cell::kValueOffset)); 3162 __ str(ip, FieldMemOperand(r5, FixedArray::kHeaderSize));
3151 } 3163 }
3152 // Check for function proxy. 3164 // Check for function proxy.
3153 __ cmp(r3, Operand(JS_FUNCTION_PROXY_TYPE)); 3165 __ cmp(r4, Operand(JS_FUNCTION_PROXY_TYPE));
3154 __ b(ne, &non_function); 3166 __ b(ne, &non_function);
3155 __ push(r1); // put proxy as additional argument 3167 __ push(r1); // put proxy as additional argument
3156 __ mov(r0, Operand(argc_ + 1, RelocInfo::NONE32)); 3168 __ mov(r0, Operand(argc_ + 1, RelocInfo::NONE32));
3157 __ mov(r2, Operand::Zero()); 3169 __ mov(r2, Operand::Zero());
3158 __ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY); 3170 __ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY);
3159 { 3171 {
3160 Handle<Code> adaptor = 3172 Handle<Code> adaptor =
3161 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); 3173 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
3162 __ Jump(adaptor, RelocInfo::CODE_TARGET); 3174 __ Jump(adaptor, RelocInfo::CODE_TARGET);
3163 } 3175 }
(...skipping 19 matching lines...) Expand all
3183 } 3195 }
3184 __ str(r0, MemOperand(sp, argc_ * kPointerSize)); 3196 __ str(r0, MemOperand(sp, argc_ * kPointerSize));
3185 __ jmp(&cont); 3197 __ jmp(&cont);
3186 } 3198 }
3187 } 3199 }
3188 3200
3189 3201
3190 void CallConstructStub::Generate(MacroAssembler* masm) { 3202 void CallConstructStub::Generate(MacroAssembler* masm) {
3191 // r0 : number of arguments 3203 // r0 : number of arguments
3192 // r1 : the function to call 3204 // r1 : the function to call
3193 // r2 : cache cell for call target 3205 // r2 : feedback vector
3206 // r3 : (only if r2 is not undefined) slot in feedback vector (Smi)
3194 Label slow, non_function_call; 3207 Label slow, non_function_call;
3195 3208
3196 // Check that the function is not a smi. 3209 // Check that the function is not a smi.
3197 __ JumpIfSmi(r1, &non_function_call); 3210 __ JumpIfSmi(r1, &non_function_call);
3198 // Check that the function is a JSFunction. 3211 // Check that the function is a JSFunction.
3199 __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE); 3212 __ CompareObjectType(r1, r4, r4, JS_FUNCTION_TYPE);
3200 __ b(ne, &slow); 3213 __ b(ne, &slow);
3201 3214
3202 if (RecordCallTarget()) { 3215 if (RecordCallTarget()) {
3203 GenerateRecordCallTarget(masm); 3216 GenerateRecordCallTarget(masm);
3204 } 3217 }
3205 3218
3206 // Jump to the function-specific construct stub. 3219 // Jump to the function-specific construct stub.
3207 Register jmp_reg = r3; 3220 Register jmp_reg = r4;
3208 __ ldr(jmp_reg, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); 3221 __ ldr(jmp_reg, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
3209 __ ldr(jmp_reg, FieldMemOperand(jmp_reg, 3222 __ ldr(jmp_reg, FieldMemOperand(jmp_reg,
3210 SharedFunctionInfo::kConstructStubOffset)); 3223 SharedFunctionInfo::kConstructStubOffset));
3211 __ add(pc, jmp_reg, Operand(Code::kHeaderSize - kHeapObjectTag)); 3224 __ add(pc, jmp_reg, Operand(Code::kHeaderSize - kHeapObjectTag));
3212 3225
3213 // r0: number of arguments 3226 // r0: number of arguments
3214 // r1: called object 3227 // r1: called object
3215 // r3: object type 3228 // r4: object type
3216 Label do_call; 3229 Label do_call;
3217 __ bind(&slow); 3230 __ bind(&slow);
3218 __ cmp(r3, Operand(JS_FUNCTION_PROXY_TYPE)); 3231 __ cmp(r4, Operand(JS_FUNCTION_PROXY_TYPE));
3219 __ b(ne, &non_function_call); 3232 __ b(ne, &non_function_call);
3220 __ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR); 3233 __ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
3221 __ jmp(&do_call); 3234 __ jmp(&do_call);
3222 3235
3223 __ bind(&non_function_call); 3236 __ bind(&non_function_call);
3224 __ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); 3237 __ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
3225 __ bind(&do_call); 3238 __ bind(&do_call);
3226 // Set expected number of arguments to zero (not changing r0). 3239 // Set expected number of arguments to zero (not changing r0).
3227 __ mov(r2, Operand::Zero()); 3240 __ mov(r2, Operand::Zero());
3228 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 3241 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
(...skipping 1939 matching lines...) Expand 10 before | Expand all | Expand 10 after
5168 ArraySingleArgumentConstructorStub stub_holey(holey_initial, 5181 ArraySingleArgumentConstructorStub stub_holey(holey_initial,
5169 DISABLE_ALLOCATION_SITES); 5182 DISABLE_ALLOCATION_SITES);
5170 __ TailCallStub(&stub_holey); 5183 __ TailCallStub(&stub_holey);
5171 5184
5172 __ bind(&normal_sequence); 5185 __ bind(&normal_sequence);
5173 ArraySingleArgumentConstructorStub stub(initial, 5186 ArraySingleArgumentConstructorStub stub(initial,
5174 DISABLE_ALLOCATION_SITES); 5187 DISABLE_ALLOCATION_SITES);
5175 __ TailCallStub(&stub); 5188 __ TailCallStub(&stub);
5176 } else if (mode == DONT_OVERRIDE) { 5189 } else if (mode == DONT_OVERRIDE) {
5177 // We are going to create a holey array, but our kind is non-holey. 5190 // We are going to create a holey array, but our kind is non-holey.
5178 // Fix kind and retry (only if we have an allocation site in the cell). 5191 // Fix kind and retry (only if we have an allocation site in the slot).
5179 __ add(r3, r3, Operand(1)); 5192 __ add(r3, r3, Operand(1));
5180 5193
5181 if (FLAG_debug_code) { 5194 if (FLAG_debug_code) {
5182 __ ldr(r5, FieldMemOperand(r2, 0)); 5195 __ ldr(r5, FieldMemOperand(r2, 0));
5183 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex); 5196 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex);
5184 __ Assert(eq, kExpectedAllocationSite); 5197 __ Assert(eq, kExpectedAllocationSite);
5185 } 5198 }
5186 5199
5187 // Save the resulting elements kind in type info. We can't just store r3 5200 // Save the resulting elements kind in type info. We can't just store r3
5188 // in the AllocationSite::transition_info field because elements kind is 5201 // in the AllocationSite::transition_info field because elements kind is
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
5276 } else { 5289 } else {
5277 UNREACHABLE(); 5290 UNREACHABLE();
5278 } 5291 }
5279 } 5292 }
5280 5293
5281 5294
5282 void ArrayConstructorStub::Generate(MacroAssembler* masm) { 5295 void ArrayConstructorStub::Generate(MacroAssembler* masm) {
5283 // ----------- S t a t e ------------- 5296 // ----------- S t a t e -------------
5284 // -- r0 : argc (only if argument_count_ == ANY) 5297 // -- r0 : argc (only if argument_count_ == ANY)
5285 // -- r1 : constructor 5298 // -- r1 : constructor
5286 // -- r2 : type info cell 5299 // -- r2 : feedback vector (fixed array or undefined)
5300 // -- r3 : slot index (if r2 is fixed array)
5287 // -- sp[0] : return address 5301 // -- sp[0] : return address
5288 // -- sp[4] : last argument 5302 // -- sp[4] : last argument
5289 // ----------------------------------- 5303 // -----------------------------------
5290 if (FLAG_debug_code) { 5304 if (FLAG_debug_code) {
5291 // The array construct code is only set for the global and natives 5305 // The array construct code is only set for the global and natives
5292 // builtin Array functions which always have maps. 5306 // builtin Array functions which always have maps.
5293 5307
5294 // Initial map for the builtin Array function should be a map. 5308 // Initial map for the builtin Array function should be a map.
5295 __ ldr(r3, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset)); 5309 __ ldr(r4, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset));
5296 // Will both indicate a NULL and a Smi. 5310 // Will both indicate a NULL and a Smi.
5297 __ tst(r3, Operand(kSmiTagMask)); 5311 __ tst(r4, Operand(kSmiTagMask));
5298 __ Assert(ne, kUnexpectedInitialMapForArrayFunction); 5312 __ Assert(ne, kUnexpectedInitialMapForArrayFunction);
5299 __ CompareObjectType(r3, r3, r4, MAP_TYPE); 5313 __ CompareObjectType(r4, r4, r5, MAP_TYPE);
5300 __ Assert(eq, kUnexpectedInitialMapForArrayFunction); 5314 __ Assert(eq, kUnexpectedInitialMapForArrayFunction);
5301 5315
5302 // We should either have undefined in ebx or a valid cell 5316 // We should either have undefined in ebx or a valid fixed array.
5303 Label okay_here; 5317 Label okay_here;
5304 Handle<Map> cell_map = masm->isolate()->factory()->cell_map(); 5318 Handle<Map> fixed_array_map = masm->isolate()->factory()->fixed_array_map();
5305 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); 5319 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex);
5306 __ b(eq, &okay_here); 5320 __ b(eq, &okay_here);
5307 __ ldr(r3, FieldMemOperand(r2, 0)); 5321 __ ldr(r4, FieldMemOperand(r2, 0));
5308 __ cmp(r3, Operand(cell_map)); 5322 __ cmp(r4, Operand(fixed_array_map));
5309 __ Assert(eq, kExpectedPropertyCellInRegisterEbx); 5323 __ Assert(eq, kExpectedFixedArrayInRegisterR2);
5324
5325 // r3 should be a smi if we don't have undefined in r2
5326 __ AssertSmi(r3);
5327
5310 __ bind(&okay_here); 5328 __ bind(&okay_here);
5311 } 5329 }
5312 5330
5313 Label no_info; 5331 Label no_info;
5314 // Get the elements kind and case on that. 5332 // Get the elements kind and case on that.
5315 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); 5333 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex);
5316 __ b(eq, &no_info); 5334 __ b(eq, &no_info);
5317 __ ldr(r2, FieldMemOperand(r2, Cell::kValueOffset)); 5335 __ add(r2, r2, Operand::PointerOffsetFromSmiKey(r3));
5336 __ ldr(r2, FieldMemOperand(r2, FixedArray::kHeaderSize));
5318 5337
5319 // If the type cell is undefined, or contains anything other than an 5338 // If the feedback vector is undefined, or contains anything other than an
5320 // AllocationSite, call an array constructor that doesn't use AllocationSites. 5339 // AllocationSite, call an array constructor that doesn't use AllocationSites.
5321 __ ldr(r4, FieldMemOperand(r2, 0)); 5340 __ ldr(r4, FieldMemOperand(r2, 0));
5322 __ CompareRoot(r4, Heap::kAllocationSiteMapRootIndex); 5341 __ CompareRoot(r4, Heap::kAllocationSiteMapRootIndex);
5323 __ b(ne, &no_info); 5342 __ b(ne, &no_info);
5324 5343
5325 __ ldr(r3, FieldMemOperand(r2, AllocationSite::kTransitionInfoOffset)); 5344 __ ldr(r3, FieldMemOperand(r2, AllocationSite::kTransitionInfoOffset));
5326 __ SmiUntag(r3); 5345 __ SmiUntag(r3);
5327 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0); 5346 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0);
5328 __ and_(r3, r3, Operand(AllocationSite::ElementsKindBits::kMask)); 5347 __ and_(r3, r3, Operand(AllocationSite::ElementsKindBits::kMask));
5329 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); 5348 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE);
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
5555 MemOperand(fp, 6 * kPointerSize), 5574 MemOperand(fp, 6 * kPointerSize),
5556 NULL); 5575 NULL);
5557 } 5576 }
5558 5577
5559 5578
5560 #undef __ 5579 #undef __
5561 5580
5562 } } // namespace v8::internal 5581 } } // namespace v8::internal
5563 5582
5564 #endif // V8_TARGET_ARCH_ARM 5583 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm/debug-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698