OLD | NEW |
---|---|
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/code-stub-assembler.h" | 5 #include "src/code-stub-assembler.h" |
6 #include "src/code-factory.h" | 6 #include "src/code-factory.h" |
7 #include "src/frames-inl.h" | 7 #include "src/frames-inl.h" |
8 #include "src/frames.h" | 8 #include "src/frames.h" |
9 #include "src/ic/handler-configuration.h" | 9 #include "src/ic/handler-configuration.h" |
10 #include "src/ic/stub-cache.h" | 10 #include "src/ic/stub-cache.h" |
(...skipping 3134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3145 | 3145 |
3146 var_value->Bind(value); | 3146 var_value->Bind(value); |
3147 | 3147 |
3148 Node* details = LoadAndUntagToWord32ObjectField(property_cell, | 3148 Node* details = LoadAndUntagToWord32ObjectField(property_cell, |
3149 PropertyCell::kDetailsOffset); | 3149 PropertyCell::kDetailsOffset); |
3150 var_details->Bind(details); | 3150 var_details->Bind(details); |
3151 | 3151 |
3152 Comment("] LoadPropertyFromGlobalDictionary"); | 3152 Comment("] LoadPropertyFromGlobalDictionary"); |
3153 } | 3153 } |
3154 | 3154 |
3155 // On entry, var_value contains the property backing store's contents, which is | |
3156 // either a value or an accessor pair, as specified by var_details. | |
3157 // On successful exit, var_value contains either the original value, or the | |
3158 // result of the getter call. | |
3159 void CodeStubAssembler::ReturnValueOrCallGetter(Variable* var_value, | |
Jakob Kummerow
2016/09/23 01:38:55
This is pulled out from below, unchanged.
Igor Sheludko
2016/09/23 07:11:24
I have a feeling that with the following signature
Jakob Kummerow
2016/09/23 18:12:22
Done.
| |
3160 Variable* var_details, | |
3161 Node* context, Node* receiver, | |
3162 Label* if_success, | |
3163 Label* if_bailout) { | |
3164 Node* details = var_details->value(); | |
3165 Node* kind = BitFieldDecode<PropertyDetails::KindField>(details); | |
3166 | |
3167 Label if_accessor(this); | |
3168 Branch(Word32Equal(kind, Int32Constant(kData)), if_success, &if_accessor); | |
3169 Bind(&if_accessor); | |
3170 { | |
3171 Node* accessor_pair = var_value->value(); | |
3172 GotoIf(Word32Equal(LoadInstanceType(accessor_pair), | |
3173 Int32Constant(ACCESSOR_INFO_TYPE)), | |
3174 if_bailout); | |
3175 AssertInstanceType(accessor_pair, ACCESSOR_PAIR_TYPE); | |
3176 Node* getter = LoadObjectField(accessor_pair, AccessorPair::kGetterOffset); | |
3177 Node* getter_map = LoadMap(getter); | |
3178 Node* instance_type = LoadMapInstanceType(getter_map); | |
3179 // FunctionTemplateInfo getters are not supported yet. | |
3180 GotoIf( | |
3181 Word32Equal(instance_type, Int32Constant(FUNCTION_TEMPLATE_INFO_TYPE)), | |
3182 if_bailout); | |
3183 | |
3184 // Return undefined if the {getter} is not callable. | |
3185 var_value->Bind(UndefinedConstant()); | |
3186 GotoIf(Word32Equal(Word32And(LoadMapBitField(getter_map), | |
3187 Int32Constant(1 << Map::kIsCallable)), | |
3188 Int32Constant(0)), | |
3189 if_success); | |
3190 | |
3191 // Call the accessor. | |
3192 Callable callable = CodeFactory::Call(isolate()); | |
3193 Node* result = CallJS(callable, context, getter, receiver); | |
3194 var_value->Bind(result); | |
3195 Goto(if_success); | |
3196 } | |
3197 } | |
3198 | |
3155 void CodeStubAssembler::TryGetOwnProperty( | 3199 void CodeStubAssembler::TryGetOwnProperty( |
3156 Node* context, Node* receiver, Node* object, Node* map, Node* instance_type, | 3200 Node* context, Node* receiver, Node* object, Node* map, Node* instance_type, |
3157 Node* unique_name, Label* if_found_value, Variable* var_value, | 3201 Node* unique_name, Label* if_found_value, Variable* var_value, |
3158 Label* if_not_found, Label* if_bailout) { | 3202 Label* if_not_found, Label* if_bailout) { |
3159 DCHECK_EQ(MachineRepresentation::kTagged, var_value->rep()); | 3203 DCHECK_EQ(MachineRepresentation::kTagged, var_value->rep()); |
3160 Comment("TryGetOwnProperty"); | 3204 Comment("TryGetOwnProperty"); |
3161 | 3205 |
3162 Variable var_meta_storage(this, MachineRepresentation::kTagged); | 3206 Variable var_meta_storage(this, MachineRepresentation::kTagged); |
3163 Variable var_entry(this, MachineType::PointerRepresentation()); | 3207 Variable var_entry(this, MachineType::PointerRepresentation()); |
3164 | 3208 |
(...skipping 27 matching lines...) Expand all Loading... | |
3192 Node* dictionary = var_meta_storage.value(); | 3236 Node* dictionary = var_meta_storage.value(); |
3193 Node* entry = var_entry.value(); | 3237 Node* entry = var_entry.value(); |
3194 | 3238 |
3195 LoadPropertyFromGlobalDictionary(dictionary, entry, &var_details, var_value, | 3239 LoadPropertyFromGlobalDictionary(dictionary, entry, &var_details, var_value, |
3196 if_not_found); | 3240 if_not_found); |
3197 Goto(&if_found); | 3241 Goto(&if_found); |
3198 } | 3242 } |
3199 // Here we have details and value which could be an accessor. | 3243 // Here we have details and value which could be an accessor. |
3200 Bind(&if_found); | 3244 Bind(&if_found); |
3201 { | 3245 { |
3202 Node* details = var_details.value(); | 3246 ReturnValueOrCallGetter(var_value, &var_details, context, receiver, |
3203 Node* kind = BitFieldDecode<PropertyDetails::KindField>(details); | 3247 if_found_value, if_bailout); |
3204 | |
3205 Label if_accessor(this); | |
3206 Branch(Word32Equal(kind, Int32Constant(kData)), if_found_value, | |
3207 &if_accessor); | |
3208 Bind(&if_accessor); | |
3209 { | |
3210 Node* accessor_pair = var_value->value(); | |
3211 GotoIf(Word32Equal(LoadInstanceType(accessor_pair), | |
3212 Int32Constant(ACCESSOR_INFO_TYPE)), | |
3213 if_bailout); | |
3214 AssertInstanceType(accessor_pair, ACCESSOR_PAIR_TYPE); | |
3215 Node* getter = | |
3216 LoadObjectField(accessor_pair, AccessorPair::kGetterOffset); | |
3217 Node* getter_map = LoadMap(getter); | |
3218 Node* instance_type = LoadMapInstanceType(getter_map); | |
3219 // FunctionTemplateInfo getters are not supported yet. | |
3220 GotoIf(Word32Equal(instance_type, | |
3221 Int32Constant(FUNCTION_TEMPLATE_INFO_TYPE)), | |
3222 if_bailout); | |
3223 | |
3224 // Return undefined if the {getter} is not callable. | |
3225 var_value->Bind(UndefinedConstant()); | |
3226 GotoIf(Word32Equal(Word32And(LoadMapBitField(getter_map), | |
3227 Int32Constant(1 << Map::kIsCallable)), | |
3228 Int32Constant(0)), | |
3229 if_found_value); | |
3230 | |
3231 // Call the accessor. | |
3232 Callable callable = CodeFactory::Call(isolate()); | |
3233 Node* result = CallJS(callable, context, getter, receiver); | |
3234 var_value->Bind(result); | |
3235 Goto(if_found_value); | |
3236 } | |
3237 } | 3248 } |
3238 } | 3249 } |
3239 | 3250 |
3240 void CodeStubAssembler::TryLookupElement(Node* object, Node* map, | 3251 void CodeStubAssembler::TryLookupElement(Node* object, Node* map, |
3241 Node* instance_type, | 3252 Node* instance_type, |
3242 Node* intptr_index, Label* if_found, | 3253 Node* intptr_index, Label* if_found, |
3243 Label* if_not_found, | 3254 Label* if_not_found, |
3244 Label* if_bailout) { | 3255 Label* if_bailout) { |
3245 // Handle special objects in runtime. | 3256 // Handle special objects in runtime. |
3246 GotoIf(Int32LessThanOrEqual(instance_type, | 3257 GotoIf(Int32LessThanOrEqual(instance_type, |
(...skipping 1218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4465 Bind(&dictionary_found); | 4476 Bind(&dictionary_found); |
4466 { | 4477 { |
4467 LoadPropertyFromNameDictionary(properties, var_name_index.value(), | 4478 LoadPropertyFromNameDictionary(properties, var_name_index.value(), |
4468 &var_details, &var_value); | 4479 &var_details, &var_value); |
4469 Goto(&if_found_on_receiver); | 4480 Goto(&if_found_on_receiver); |
4470 } | 4481 } |
4471 } | 4482 } |
4472 | 4483 |
4473 Bind(&if_found_on_receiver); | 4484 Bind(&if_found_on_receiver); |
4474 { | 4485 { |
4475 Node* kind = | 4486 Label return_value(this); |
4476 BitFieldDecode<PropertyDetails::KindField>(var_details.value()); | 4487 ReturnValueOrCallGetter(&var_value, &var_details, p->context, receiver, |
4477 // TODO(jkummerow): Support accessors without missing? | 4488 &return_value, &slow); |
4478 GotoUnless(Word32Equal(kind, Int32Constant(kData)), &slow); | 4489 Bind(&return_value); |
4479 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_symbol(), 1); | 4490 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_symbol(), 1); |
4480 Return(var_value.value()); | 4491 Return(var_value.value()); |
4481 } | 4492 } |
4482 | 4493 |
4483 Bind(&slow); | 4494 Bind(&slow); |
4484 { | 4495 { |
4485 Comment("KeyedLoadGeneric_slow"); | 4496 Comment("KeyedLoadGeneric_slow"); |
4486 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_slow(), 1); | 4497 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_slow(), 1); |
4487 // TODO(jkummerow): Should we use the GetProperty TF stub instead? | 4498 // TODO(jkummerow): Should we use the GetProperty TF stub instead? |
4488 TailCallRuntime(Runtime::kKeyedGetProperty, p->context, p->receiver, | 4499 TailCallRuntime(Runtime::kKeyedGetProperty, p->context, p->receiver, |
(...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5214 Heap::kTheHoleValueRootIndex); | 5225 Heap::kTheHoleValueRootIndex); |
5215 | 5226 |
5216 // Store the WeakCell in the feedback vector. | 5227 // Store the WeakCell in the feedback vector. |
5217 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, | 5228 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, |
5218 CodeStubAssembler::SMI_PARAMETERS); | 5229 CodeStubAssembler::SMI_PARAMETERS); |
5219 return cell; | 5230 return cell; |
5220 } | 5231 } |
5221 | 5232 |
5222 } // namespace internal | 5233 } // namespace internal |
5223 } // namespace v8 | 5234 } // namespace v8 |
OLD | NEW |