OLD | NEW |
---|---|
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...) Loading... | |
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 2890 matching lines...) Loading... | |
3010 // Load offset into r9 and replace subject string with parent. | 3010 // Load offset into r9 and replace subject string with parent. |
3011 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset)); | 3011 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset)); |
3012 __ SmiUntag(r9); | 3012 __ SmiUntag(r9); |
3013 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); | 3013 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); |
3014 __ jmp(&check_underlying); // Go to (4). | 3014 __ jmp(&check_underlying); // Go to (4). |
3015 #endif // V8_INTERPRETED_REGEXP | 3015 #endif // V8_INTERPRETED_REGEXP |
3016 } | 3016 } |
3017 | 3017 |
3018 | 3018 |
3019 static void GenerateRecordCallTarget(MacroAssembler* masm) { | 3019 static void GenerateRecordCallTarget(MacroAssembler* masm) { |
3020 // Cache the called function in a global property cell. Cache states | 3020 // Cache the called function in a global property cell. Cache states |
Benedikt Meurer
2014/02/04 08:53:50
Nit: global property cell -> feedback vector slot.
mvstanton
2014/02/04 13:03:27
Done.
| |
3021 // are uninitialized, monomorphic (indicated by a JSFunction), and | 3021 // are uninitialized, monomorphic (indicated by a JSFunction), and |
3022 // megamorphic. | 3022 // megamorphic. |
3023 // r0 : number of arguments to the construct function | 3023 // r0 : number of arguments to the construct function |
3024 // r1 : the function to call | 3024 // r1 : the function to call |
3025 // r2 : cache cell for call target | 3025 // r2 : Feedback vector |
3026 // r3 : slot in feedback vector (Smi) | |
3026 Label initialize, done, miss, megamorphic, not_array_function; | 3027 Label initialize, done, miss, megamorphic, not_array_function; |
3027 | 3028 |
3028 ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()), | 3029 ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()), |
3029 masm->isolate()->heap()->undefined_value()); | 3030 masm->isolate()->heap()->undefined_value()); |
3030 ASSERT_EQ(*TypeFeedbackCells::UninitializedSentinel(masm->isolate()), | 3031 ASSERT_EQ(*TypeFeedbackInfo::UninitializedSentinel(masm->isolate()), |
3031 masm->isolate()->heap()->the_hole_value()); | 3032 masm->isolate()->heap()->the_hole_value()); |
3032 | 3033 |
3033 // Load the cache state into r3. | 3034 // Load the cache state into r4. |
3034 __ ldr(r3, FieldMemOperand(r2, Cell::kValueOffset)); | 3035 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); |
3036 __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize)); | |
3035 | 3037 |
3036 // A monomorphic cache hit or an already megamorphic state: invoke the | 3038 // A monomorphic cache hit or an already megamorphic state: invoke the |
3037 // function without changing the state. | 3039 // function without changing the state. |
3038 __ cmp(r3, r1); | 3040 __ cmp(r4, r1); |
3039 __ b(eq, &done); | 3041 __ b(eq, &done); |
3040 | 3042 |
3041 // If we came here, we need to see if we are the array function. | 3043 // If we came here, we need to see if we are the array function. |
3042 // If we didn't have a matching function, and we didn't find the megamorph | 3044 // If we didn't have a matching function, and we didn't find the megamorph |
3043 // sentinel, then we have in the cell either some other function or an | 3045 // sentinel, then we have in the cell either some other function or an |
3044 // AllocationSite. Do a map check on the object in ecx. | 3046 // AllocationSite. Do a map check on the object in ecx. |
3045 __ ldr(r5, FieldMemOperand(r3, 0)); | 3047 __ ldr(r5, FieldMemOperand(r4, 0)); |
3046 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex); | 3048 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex); |
3047 __ b(ne, &miss); | 3049 __ b(ne, &miss); |
3048 | 3050 |
3049 // Make sure the function is the Array() function | 3051 // Make sure the function is the Array() function |
3050 __ LoadArrayFunction(r3); | 3052 __ LoadArrayFunction(r4); |
3051 __ cmp(r1, r3); | 3053 __ cmp(r1, r4); |
3052 __ b(ne, &megamorphic); | 3054 __ b(ne, &megamorphic); |
3053 __ jmp(&done); | 3055 __ jmp(&done); |
3054 | 3056 |
3055 __ bind(&miss); | 3057 __ bind(&miss); |
3056 | 3058 |
3057 // A monomorphic miss (i.e, here the cache is not uninitialized) goes | 3059 // A monomorphic miss (i.e, here the cache is not uninitialized) goes |
3058 // megamorphic. | 3060 // megamorphic. |
3059 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); | 3061 __ CompareRoot(r4, Heap::kTheHoleValueRootIndex); |
3060 __ b(eq, &initialize); | 3062 __ b(eq, &initialize); |
3061 // MegamorphicSentinel is an immortal immovable object (undefined) so no | 3063 // MegamorphicSentinel is an immortal immovable object (undefined) so no |
3062 // write-barrier is needed. | 3064 // write-barrier is needed. |
3063 __ bind(&megamorphic); | 3065 __ bind(&megamorphic); |
3066 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); | |
3064 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 3067 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
3065 __ str(ip, FieldMemOperand(r2, Cell::kValueOffset)); | 3068 __ str(ip, FieldMemOperand(r4, FixedArray::kHeaderSize)); |
3066 __ jmp(&done); | 3069 __ jmp(&done); |
3067 | 3070 |
3068 // An uninitialized cache is patched with the function or sentinel to | 3071 // An uninitialized cache is patched with the function or sentinel to |
3069 // indicate the ElementsKind if function is the Array constructor. | 3072 // indicate the ElementsKind if function is the Array constructor. |
3070 __ bind(&initialize); | 3073 __ bind(&initialize); |
3071 // Make sure the function is the Array() function | 3074 // Make sure the function is the Array() function |
3072 __ LoadArrayFunction(r3); | 3075 __ LoadArrayFunction(r4); |
3073 __ cmp(r1, r3); | 3076 __ cmp(r1, r4); |
3074 __ b(ne, ¬_array_function); | 3077 __ b(ne, ¬_array_function); |
3075 | 3078 |
3076 // The target function is the Array constructor, | 3079 // The target function is the Array constructor, |
3077 // Create an AllocationSite if we don't already have it, store it in the cell | 3080 // Create an AllocationSite if we don't already have it, store it in the cell |
Benedikt Meurer
2014/02/04 08:53:50
Nit: cell -> slot.
mvstanton
2014/02/04 13:03:27
Done.
| |
3078 { | 3081 { |
3079 FrameScope scope(masm, StackFrame::INTERNAL); | 3082 FrameScope scope(masm, StackFrame::INTERNAL); |
3080 | 3083 |
3081 // Arguments register must be smi-tagged to call out. | 3084 // Arguments register must be smi-tagged to call out. |
3082 __ SmiTag(r0); | 3085 __ SmiTag(r0); |
3083 __ Push(r2, r1, r0); | 3086 __ Push(r3, r2, r1, r0); |
3084 | 3087 |
3085 CreateAllocationSiteStub create_stub; | 3088 CreateAllocationSiteStub create_stub; |
3086 __ CallStub(&create_stub); | 3089 __ CallStub(&create_stub); |
3087 | 3090 |
3088 __ Pop(r2, r1, r0); | 3091 __ Pop(r3, r2, r1, r0); |
3089 __ SmiUntag(r0); | 3092 __ SmiUntag(r0); |
3090 } | 3093 } |
3091 __ b(&done); | 3094 __ b(&done); |
3092 | 3095 |
3093 __ bind(¬_array_function); | 3096 __ bind(¬_array_function); |
3094 __ str(r1, FieldMemOperand(r2, Cell::kValueOffset)); | 3097 |
3095 // No need for a write barrier here - cells are rescanned. | 3098 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); |
3099 __ add(r4, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | |
3100 __ str(r1, MemOperand(r4, 0)); | |
3101 | |
3102 __ Push(r4, r2, r1); | |
3103 __ RecordWrite(r2, r4, r1, kLRHasNotBeenSaved, kDontSaveFPRegs, | |
3104 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); | |
3105 __ Pop(r4, r2, r1); | |
3096 | 3106 |
3097 __ bind(&done); | 3107 __ bind(&done); |
3098 } | 3108 } |
3099 | 3109 |
3100 | 3110 |
3101 void CallFunctionStub::Generate(MacroAssembler* masm) { | 3111 void CallFunctionStub::Generate(MacroAssembler* masm) { |
3102 // r1 : the function to call | 3112 // r1 : the function to call |
3103 // r2 : cache cell for call target | 3113 // r2 : feedback vector |
3114 // r3 : (only if r2 is not undefined) slot in feedback vector (Smi) | |
3104 Label slow, non_function; | 3115 Label slow, non_function; |
3105 | 3116 |
3106 // Check that the function is really a JavaScript function. | 3117 // Check that the function is really a JavaScript function. |
3107 // r1: pushed function (to be verified) | 3118 // r1: pushed function (to be verified) |
3108 __ JumpIfSmi(r1, &non_function); | 3119 __ JumpIfSmi(r1, &non_function); |
3109 | 3120 |
3110 // Goto slow case if we do not have a function. | 3121 // Goto slow case if we do not have a function. |
3111 __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE); | 3122 __ CompareObjectType(r1, r4, r4, JS_FUNCTION_TYPE); |
3112 __ b(ne, &slow); | 3123 __ b(ne, &slow); |
3113 | 3124 |
3114 if (RecordCallTarget()) { | 3125 if (RecordCallTarget()) { |
3115 GenerateRecordCallTarget(masm); | 3126 GenerateRecordCallTarget(masm); |
3116 } | 3127 } |
3117 | 3128 |
3118 // Fast-case: Invoke the function now. | 3129 // Fast-case: Invoke the function now. |
3119 // r1: pushed function | 3130 // r1: pushed function |
3120 ParameterCount actual(argc_); | 3131 ParameterCount actual(argc_); |
3121 | 3132 |
3122 __ InvokeFunction(r1, actual, JUMP_FUNCTION, NullCallWrapper()); | 3133 __ InvokeFunction(r1, actual, JUMP_FUNCTION, NullCallWrapper()); |
3123 | 3134 |
3124 // Slow-case: Non-function called. | 3135 // Slow-case: Non-function called. |
3125 __ bind(&slow); | 3136 __ bind(&slow); |
3126 if (RecordCallTarget()) { | 3137 if (RecordCallTarget()) { |
3127 // If there is a call target cache, mark it megamorphic in the | 3138 // If there is a call target cache, mark it megamorphic in the |
3128 // non-function case. MegamorphicSentinel is an immortal immovable | 3139 // non-function case. MegamorphicSentinel is an immortal immovable |
3129 // object (undefined) so no write barrier is needed. | 3140 // object (undefined) so no write barrier is needed. |
3130 ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()), | 3141 ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()), |
3131 masm->isolate()->heap()->undefined_value()); | 3142 masm->isolate()->heap()->undefined_value()); |
3143 __ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3)); | |
3132 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 3144 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
3133 __ str(ip, FieldMemOperand(r2, Cell::kValueOffset)); | 3145 __ str(ip, FieldMemOperand(r5, FixedArray::kHeaderSize)); |
3134 } | 3146 } |
3135 // Check for function proxy. | 3147 // Check for function proxy. |
3136 __ cmp(r3, Operand(JS_FUNCTION_PROXY_TYPE)); | 3148 __ cmp(r4, Operand(JS_FUNCTION_PROXY_TYPE)); |
3137 __ b(ne, &non_function); | 3149 __ b(ne, &non_function); |
3138 __ push(r1); // put proxy as additional argument | 3150 __ push(r1); // put proxy as additional argument |
3139 __ mov(r0, Operand(argc_ + 1, RelocInfo::NONE32)); | 3151 __ mov(r0, Operand(argc_ + 1, RelocInfo::NONE32)); |
3140 __ mov(r2, Operand::Zero()); | 3152 __ mov(r2, Operand::Zero()); |
3141 __ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY); | 3153 __ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY); |
3142 { | 3154 { |
3143 Handle<Code> adaptor = | 3155 Handle<Code> adaptor = |
3144 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); | 3156 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); |
3145 __ Jump(adaptor, RelocInfo::CODE_TARGET); | 3157 __ Jump(adaptor, RelocInfo::CODE_TARGET); |
3146 } | 3158 } |
3147 | 3159 |
3148 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead | 3160 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead |
3149 // of the original receiver from the call site). | 3161 // of the original receiver from the call site). |
3150 __ bind(&non_function); | 3162 __ bind(&non_function); |
3151 __ str(r1, MemOperand(sp, argc_ * kPointerSize)); | 3163 __ str(r1, MemOperand(sp, argc_ * kPointerSize)); |
3152 __ mov(r0, Operand(argc_)); // Set up the number of arguments. | 3164 __ mov(r0, Operand(argc_)); // Set up the number of arguments. |
3153 __ mov(r2, Operand::Zero()); | 3165 __ mov(r2, Operand::Zero()); |
3154 __ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION); | 3166 __ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION); |
3155 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 3167 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
3156 RelocInfo::CODE_TARGET); | 3168 RelocInfo::CODE_TARGET); |
3157 } | 3169 } |
3158 | 3170 |
3159 | 3171 |
3160 void CallConstructStub::Generate(MacroAssembler* masm) { | 3172 void CallConstructStub::Generate(MacroAssembler* masm) { |
3161 // r0 : number of arguments | 3173 // r0 : number of arguments |
3162 // r1 : the function to call | 3174 // r1 : the function to call |
3163 // r2 : cache cell for call target | 3175 // r2 : feedback vector |
3176 // r3 : (only if r2 is not undefined) slot in feedback vector (Smi) | |
3164 Label slow, non_function_call; | 3177 Label slow, non_function_call; |
3165 | 3178 |
3166 // Check that the function is not a smi. | 3179 // Check that the function is not a smi. |
3167 __ JumpIfSmi(r1, &non_function_call); | 3180 __ JumpIfSmi(r1, &non_function_call); |
3168 // Check that the function is a JSFunction. | 3181 // Check that the function is a JSFunction. |
3169 __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE); | 3182 __ CompareObjectType(r1, r4, r4, JS_FUNCTION_TYPE); |
3170 __ b(ne, &slow); | 3183 __ b(ne, &slow); |
3171 | 3184 |
3172 if (RecordCallTarget()) { | 3185 if (RecordCallTarget()) { |
3173 GenerateRecordCallTarget(masm); | 3186 GenerateRecordCallTarget(masm); |
3174 } | 3187 } |
3175 | 3188 |
3176 // Jump to the function-specific construct stub. | 3189 // Jump to the function-specific construct stub. |
3177 Register jmp_reg = r3; | 3190 Register jmp_reg = r4; |
3178 __ ldr(jmp_reg, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); | 3191 __ ldr(jmp_reg, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
3179 __ ldr(jmp_reg, FieldMemOperand(jmp_reg, | 3192 __ ldr(jmp_reg, FieldMemOperand(jmp_reg, |
3180 SharedFunctionInfo::kConstructStubOffset)); | 3193 SharedFunctionInfo::kConstructStubOffset)); |
3181 __ add(pc, jmp_reg, Operand(Code::kHeaderSize - kHeapObjectTag)); | 3194 __ add(pc, jmp_reg, Operand(Code::kHeaderSize - kHeapObjectTag)); |
3182 | 3195 |
3183 // r0: number of arguments | 3196 // r0: number of arguments |
3184 // r1: called object | 3197 // r1: called object |
3185 // r3: object type | 3198 // r4: object type |
3186 Label do_call; | 3199 Label do_call; |
3187 __ bind(&slow); | 3200 __ bind(&slow); |
3188 __ cmp(r3, Operand(JS_FUNCTION_PROXY_TYPE)); | 3201 __ cmp(r4, Operand(JS_FUNCTION_PROXY_TYPE)); |
3189 __ b(ne, &non_function_call); | 3202 __ b(ne, &non_function_call); |
3190 __ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR); | 3203 __ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR); |
3191 __ jmp(&do_call); | 3204 __ jmp(&do_call); |
3192 | 3205 |
3193 __ bind(&non_function_call); | 3206 __ bind(&non_function_call); |
3194 __ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); | 3207 __ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); |
3195 __ bind(&do_call); | 3208 __ bind(&do_call); |
3196 // Set expected number of arguments to zero (not changing r0). | 3209 // Set expected number of arguments to zero (not changing r0). |
3197 __ mov(r2, Operand::Zero()); | 3210 __ mov(r2, Operand::Zero()); |
3198 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 3211 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), |
(...skipping 2064 matching lines...) Loading... | |
5263 } else { | 5276 } else { |
5264 UNREACHABLE(); | 5277 UNREACHABLE(); |
5265 } | 5278 } |
5266 } | 5279 } |
5267 | 5280 |
5268 | 5281 |
5269 void ArrayConstructorStub::Generate(MacroAssembler* masm) { | 5282 void ArrayConstructorStub::Generate(MacroAssembler* masm) { |
5270 // ----------- S t a t e ------------- | 5283 // ----------- S t a t e ------------- |
5271 // -- r0 : argc (only if argument_count_ == ANY) | 5284 // -- r0 : argc (only if argument_count_ == ANY) |
5272 // -- r1 : constructor | 5285 // -- r1 : constructor |
5273 // -- r2 : type info cell | 5286 // -- r2 : feedback vector (fixed array or undefined) |
5287 // -- r3 : slot index (if r2 is fixed array) | |
5274 // -- sp[0] : return address | 5288 // -- sp[0] : return address |
5275 // -- sp[4] : last argument | 5289 // -- sp[4] : last argument |
5276 // ----------------------------------- | 5290 // ----------------------------------- |
5277 if (FLAG_debug_code) { | 5291 if (FLAG_debug_code) { |
5278 // The array construct code is only set for the global and natives | 5292 // The array construct code is only set for the global and natives |
5279 // builtin Array functions which always have maps. | 5293 // builtin Array functions which always have maps. |
5280 | 5294 |
5281 // Initial map for the builtin Array function should be a map. | 5295 // Initial map for the builtin Array function should be a map. |
5282 __ ldr(r3, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset)); | 5296 __ ldr(r3, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset)); |
5283 // Will both indicate a NULL and a Smi. | 5297 // Will both indicate a NULL and a Smi. |
5284 __ tst(r3, Operand(kSmiTagMask)); | 5298 __ tst(r3, Operand(kSmiTagMask)); |
5285 __ Assert(ne, kUnexpectedInitialMapForArrayFunction); | 5299 __ Assert(ne, kUnexpectedInitialMapForArrayFunction); |
5286 __ CompareObjectType(r3, r3, r4, MAP_TYPE); | 5300 __ CompareObjectType(r3, r3, r4, MAP_TYPE); |
5287 __ Assert(eq, kUnexpectedInitialMapForArrayFunction); | 5301 __ Assert(eq, kUnexpectedInitialMapForArrayFunction); |
5288 | 5302 |
5289 // We should either have undefined in ebx or a valid cell | 5303 // We should either have undefined in ebx or a valid cell |
5290 Label okay_here; | 5304 Label okay_here; |
5291 Handle<Map> cell_map = masm->isolate()->factory()->cell_map(); | 5305 Handle<Map> fixed_array_map = masm->isolate()->factory()->fixed_array_map(); |
5292 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); | 5306 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); |
5293 __ b(eq, &okay_here); | 5307 __ b(eq, &okay_here); |
5294 __ ldr(r3, FieldMemOperand(r2, 0)); | 5308 __ ldr(r4, FieldMemOperand(r2, 0)); |
5295 __ cmp(r3, Operand(cell_map)); | 5309 __ cmp(r4, Operand(fixed_array_map)); |
5296 __ Assert(eq, kExpectedPropertyCellInRegisterEbx); | 5310 __ Assert(eq, kExpectedFixedArrayInRegisterR2); |
5311 | |
5312 // r3 should be a smi if we don't have undefined in r2 | |
5313 __ AssertSmi(r3); | |
5314 | |
5297 __ bind(&okay_here); | 5315 __ bind(&okay_here); |
5298 } | 5316 } |
5299 | 5317 |
5300 Label no_info; | 5318 Label no_info; |
5301 // Get the elements kind and case on that. | 5319 // Get the elements kind and case on that. |
5302 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); | 5320 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); |
5303 __ b(eq, &no_info); | 5321 __ b(eq, &no_info); |
5304 __ ldr(r2, FieldMemOperand(r2, Cell::kValueOffset)); | 5322 __ add(r2, r2, Operand::PointerOffsetFromSmiKey(r3)); |
5323 __ ldr(r2, FieldMemOperand(r2, FixedArray::kHeaderSize)); | |
5305 | 5324 |
5306 // If the type cell is undefined, or contains anything other than an | 5325 // If the type cell is undefined, or contains anything other than an |
5307 // AllocationSite, call an array constructor that doesn't use AllocationSites. | 5326 // AllocationSite, call an array constructor that doesn't use AllocationSites. |
5308 __ ldr(r4, FieldMemOperand(r2, 0)); | 5327 __ ldr(r4, FieldMemOperand(r2, 0)); |
5309 __ CompareRoot(r4, Heap::kAllocationSiteMapRootIndex); | 5328 __ CompareRoot(r4, Heap::kAllocationSiteMapRootIndex); |
5310 __ b(ne, &no_info); | 5329 __ b(ne, &no_info); |
5311 | 5330 |
5312 __ ldr(r3, FieldMemOperand(r2, AllocationSite::kTransitionInfoOffset)); | 5331 __ ldr(r3, FieldMemOperand(r2, AllocationSite::kTransitionInfoOffset)); |
5313 __ SmiUntag(r3); | 5332 __ SmiUntag(r3); |
5314 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0); | 5333 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0); |
(...skipping 227 matching lines...) Loading... | |
5542 MemOperand(fp, 6 * kPointerSize), | 5561 MemOperand(fp, 6 * kPointerSize), |
5543 NULL); | 5562 NULL); |
5544 } | 5563 } |
5545 | 5564 |
5546 | 5565 |
5547 #undef __ | 5566 #undef __ |
5548 | 5567 |
5549 } } // namespace v8::internal | 5568 } } // namespace v8::internal |
5550 | 5569 |
5551 #endif // V8_TARGET_ARCH_ARM | 5570 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |