Chromium Code Reviews| 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 |