| OLD | NEW | 
|     1 // Copyright 2012 the V8 project authors. All rights reserved. |     1 // Copyright 2012 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 #ifndef V8_HYDROGEN_H_ |     5 #ifndef V8_HYDROGEN_H_ | 
|     6 #define V8_HYDROGEN_H_ |     6 #define V8_HYDROGEN_H_ | 
|     7  |     7  | 
|     8 #include "src/v8.h" |     8 #include "src/v8.h" | 
|     9  |     9  | 
|    10 #include "src/accessors.h" |    10 #include "src/accessors.h" | 
| (...skipping 2412 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2423       HValue* object, HIfContinuation* continuation); |  2423       HValue* object, HIfContinuation* continuation); | 
|  2424  |  2424  | 
|  2425   Handle<JSFunction> array_function() { |  2425   Handle<JSFunction> array_function() { | 
|  2426     return handle(isolate()->native_context()->array_function()); |  2426     return handle(isolate()->native_context()->array_function()); | 
|  2427   } |  2427   } | 
|  2428  |  2428  | 
|  2429   bool IsCallArrayInlineable(int argument_count, Handle<AllocationSite> site); |  2429   bool IsCallArrayInlineable(int argument_count, Handle<AllocationSite> site); | 
|  2430   void BuildInlinedCallArray(Expression* expression, int argument_count, |  2430   void BuildInlinedCallArray(Expression* expression, int argument_count, | 
|  2431                              Handle<AllocationSite> site); |  2431                              Handle<AllocationSite> site); | 
|  2432  |  2432  | 
|  2433   class LookupResult FINAL BASE_EMBEDDED { |  | 
|  2434    public: |  | 
|  2435     LookupResult() |  | 
|  2436         : lookup_type_(NOT_FOUND), |  | 
|  2437           details_(NONE, DATA, Representation::None()) {} |  | 
|  2438  |  | 
|  2439     void LookupDescriptor(Map* map, Name* name) { |  | 
|  2440       DescriptorArray* descriptors = map->instance_descriptors(); |  | 
|  2441       int number = descriptors->SearchWithCache(name, map); |  | 
|  2442       if (number == DescriptorArray::kNotFound) return NotFound(); |  | 
|  2443       lookup_type_ = DESCRIPTOR_TYPE; |  | 
|  2444       details_ = descriptors->GetDetails(number); |  | 
|  2445       number_ = number; |  | 
|  2446     } |  | 
|  2447  |  | 
|  2448     void LookupTransition(Map* map, Name* name, PropertyAttributes attributes) { |  | 
|  2449       int transition_index = map->SearchTransition(kData, name, attributes); |  | 
|  2450       if (transition_index == TransitionArray::kNotFound) return NotFound(); |  | 
|  2451       lookup_type_ = TRANSITION_TYPE; |  | 
|  2452       transition_ = handle(map->GetTransition(transition_index)); |  | 
|  2453       number_ = transition_->LastAdded(); |  | 
|  2454       details_ = transition_->instance_descriptors()->GetDetails(number_); |  | 
|  2455     } |  | 
|  2456  |  | 
|  2457     void NotFound() { |  | 
|  2458       lookup_type_ = NOT_FOUND; |  | 
|  2459       details_ = PropertyDetails(NONE, DATA, 0); |  | 
|  2460     } |  | 
|  2461  |  | 
|  2462     Representation representation() const { |  | 
|  2463       DCHECK(IsFound()); |  | 
|  2464       return details_.representation(); |  | 
|  2465     } |  | 
|  2466  |  | 
|  2467     // Property callbacks does not include transitions to callbacks. |  | 
|  2468     bool IsAccessorConstant() const { |  | 
|  2469       return !IsTransition() && details_.type() == ACCESSOR_CONSTANT; |  | 
|  2470     } |  | 
|  2471  |  | 
|  2472     bool IsReadOnly() const { |  | 
|  2473       DCHECK(IsFound()); |  | 
|  2474       return details_.IsReadOnly(); |  | 
|  2475     } |  | 
|  2476  |  | 
|  2477     bool IsData() const { |  | 
|  2478       return lookup_type_ == DESCRIPTOR_TYPE && details_.type() == DATA; |  | 
|  2479     } |  | 
|  2480  |  | 
|  2481     bool IsDataConstant() const { |  | 
|  2482       return lookup_type_ == DESCRIPTOR_TYPE && |  | 
|  2483              details_.type() == DATA_CONSTANT; |  | 
|  2484     } |  | 
|  2485  |  | 
|  2486     bool IsConfigurable() const { return details_.IsConfigurable(); } |  | 
|  2487     bool IsFound() const { return lookup_type_ != NOT_FOUND; } |  | 
|  2488     bool IsTransition() const { return lookup_type_ == TRANSITION_TYPE; } |  | 
|  2489  |  | 
|  2490     // Is the result is a property excluding transitions and the null |  | 
|  2491     // descriptor? |  | 
|  2492     bool IsProperty() const { return IsFound() && !IsTransition(); } |  | 
|  2493  |  | 
|  2494     Handle<Map> GetTransitionTarget() const { |  | 
|  2495       DCHECK(IsTransition()); |  | 
|  2496       return transition_; |  | 
|  2497     } |  | 
|  2498  |  | 
|  2499     bool IsTransitionToData() const { |  | 
|  2500       return IsTransition() && details_.type() == DATA; |  | 
|  2501     } |  | 
|  2502  |  | 
|  2503     int GetLocalFieldIndexFromMap(Map* map) const { |  | 
|  2504       return GetFieldIndexFromMap(map) - map->inobject_properties(); |  | 
|  2505     } |  | 
|  2506  |  | 
|  2507     Object* GetConstantFromMap(Map* map) const { |  | 
|  2508       DCHECK(details_.type() == DATA_CONSTANT); |  | 
|  2509       return GetValueFromMap(map); |  | 
|  2510     } |  | 
|  2511  |  | 
|  2512     Object* GetValueFromMap(Map* map) const { |  | 
|  2513       DCHECK(lookup_type_ == DESCRIPTOR_TYPE || |  | 
|  2514              lookup_type_ == TRANSITION_TYPE); |  | 
|  2515       DCHECK(number_ < map->NumberOfOwnDescriptors()); |  | 
|  2516       return map->instance_descriptors()->GetValue(number_); |  | 
|  2517     } |  | 
|  2518  |  | 
|  2519     int GetFieldIndexFromMap(Map* map) const { |  | 
|  2520       DCHECK(lookup_type_ == DESCRIPTOR_TYPE || |  | 
|  2521              lookup_type_ == TRANSITION_TYPE); |  | 
|  2522       DCHECK(number_ < map->NumberOfOwnDescriptors()); |  | 
|  2523       return map->instance_descriptors()->GetFieldIndex(number_); |  | 
|  2524     } |  | 
|  2525  |  | 
|  2526     HeapType* GetFieldTypeFromMap(Map* map) const { |  | 
|  2527       DCHECK_NE(NOT_FOUND, lookup_type_); |  | 
|  2528       DCHECK(number_ < map->NumberOfOwnDescriptors()); |  | 
|  2529       return map->instance_descriptors()->GetFieldType(number_); |  | 
|  2530     } |  | 
|  2531  |  | 
|  2532     Map* GetFieldOwnerFromMap(Map* map) const { |  | 
|  2533       DCHECK(lookup_type_ == DESCRIPTOR_TYPE || |  | 
|  2534              lookup_type_ == TRANSITION_TYPE); |  | 
|  2535       DCHECK(number_ < map->NumberOfOwnDescriptors()); |  | 
|  2536       return map->FindFieldOwner(number_); |  | 
|  2537     } |  | 
|  2538  |  | 
|  2539    private: |  | 
|  2540     // Where did we find the result; |  | 
|  2541     enum { NOT_FOUND, DESCRIPTOR_TYPE, TRANSITION_TYPE } lookup_type_; |  | 
|  2542  |  | 
|  2543     Handle<Map> transition_; |  | 
|  2544     int number_; |  | 
|  2545     PropertyDetails details_; |  | 
|  2546   }; |  | 
|  2547  |  | 
|  2548   class PropertyAccessInfo { |  2433   class PropertyAccessInfo { | 
|  2549    public: |  2434    public: | 
|  2550     PropertyAccessInfo(HOptimizedGraphBuilder* builder, |  2435     PropertyAccessInfo(HOptimizedGraphBuilder* builder, | 
|  2551                        PropertyAccessType access_type, Handle<Map> map, |  2436                        PropertyAccessType access_type, Handle<Map> map, | 
|  2552                        Handle<String> name) |  2437                        Handle<String> name) | 
|  2553         : builder_(builder), |  2438         : builder_(builder), | 
|  2554           access_type_(access_type), |  2439           access_type_(access_type), | 
|  2555           map_(map), |  2440           map_(map), | 
|  2556           name_(name), |  2441           name_(name), | 
|  2557           field_type_(HType::Tagged()), |  2442           field_type_(HType::Tagged()), | 
|  2558           access_(HObjectAccess::ForMap()) {} |  2443           access_(HObjectAccess::ForMap()), | 
 |  2444           lookup_type_(NOT_FOUND), | 
 |  2445           details_(NONE, DATA, Representation::None()) {} | 
|  2559  |  2446  | 
|  2560     // Checkes whether this PropertyAccessInfo can be handled as a monomorphic |  2447     // Checkes whether this PropertyAccessInfo can be handled as a monomorphic | 
|  2561     // load named. It additionally fills in the fields necessary to generate the |  2448     // load named. It additionally fills in the fields necessary to generate the | 
|  2562     // lookup code. |  2449     // lookup code. | 
|  2563     bool CanAccessMonomorphic(); |  2450     bool CanAccessMonomorphic(); | 
|  2564  |  2451  | 
|  2565     // Checks whether all types behave uniform when loading name. If all maps |  2452     // Checks whether all types behave uniform when loading name. If all maps | 
|  2566     // behave the same, a single monomorphic load instruction can be emitted, |  2453     // behave the same, a single monomorphic load instruction can be emitted, | 
|  2567     // guarded by a single map-checks instruction that whether the receiver is |  2454     // guarded by a single map-checks instruction that whether the receiver is | 
|  2568     // an instance of any of the types. |  2455     // an instance of any of the types. | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
|  2597       return false; |  2484       return false; | 
|  2598     } |  2485     } | 
|  2599  |  2486  | 
|  2600     bool has_holder() { return !holder_.is_null(); } |  2487     bool has_holder() { return !holder_.is_null(); } | 
|  2601     bool IsLoad() const { return access_type_ == LOAD; } |  2488     bool IsLoad() const { return access_type_ == LOAD; } | 
|  2602  |  2489  | 
|  2603     Isolate* isolate() const { return builder_->isolate(); } |  2490     Isolate* isolate() const { return builder_->isolate(); } | 
|  2604     Handle<JSObject> holder() { return holder_; } |  2491     Handle<JSObject> holder() { return holder_; } | 
|  2605     Handle<JSFunction> accessor() { return accessor_; } |  2492     Handle<JSFunction> accessor() { return accessor_; } | 
|  2606     Handle<Object> constant() { return constant_; } |  2493     Handle<Object> constant() { return constant_; } | 
|  2607     Handle<Map> transition() { return lookup_.GetTransitionTarget(); } |  2494     Handle<Map> transition() { return transition_; } | 
|  2608     SmallMapList* field_maps() { return &field_maps_; } |  2495     SmallMapList* field_maps() { return &field_maps_; } | 
|  2609     HType field_type() const { return field_type_; } |  2496     HType field_type() const { return field_type_; } | 
|  2610     HObjectAccess access() { return access_; } |  2497     HObjectAccess access() { return access_; } | 
|  2611  |  2498  | 
|  2612     bool IsFound() const { return lookup_.IsFound(); } |  2499     bool IsFound() const { return lookup_type_ != NOT_FOUND; } | 
|  2613     bool IsProperty() const { return lookup_.IsProperty(); } |  2500     bool IsProperty() const { return IsFound() && !IsTransition(); } | 
|  2614     bool IsData() const { return lookup_.IsData(); } |  2501     bool IsTransition() const { return lookup_type_ == TRANSITION_TYPE; } | 
|  2615     bool IsDataConstant() const { return lookup_.IsDataConstant(); } |  2502     bool IsData() const { | 
|  2616     bool IsAccessorConstant() const { return lookup_.IsAccessorConstant(); } |  2503       return lookup_type_ == DESCRIPTOR_TYPE && details_.type() == DATA; | 
|  2617     bool IsTransition() const { return lookup_.IsTransition(); } |  2504     } | 
|  2618  |  2505     bool IsDataConstant() const { | 
|  2619     bool IsConfigurable() const { return lookup_.IsConfigurable(); } |  2506       return lookup_type_ == DESCRIPTOR_TYPE && | 
|  2620     bool IsReadOnly() const { return lookup_.IsReadOnly(); } |  2507              details_.type() == DATA_CONSTANT; | 
 |  2508     } | 
 |  2509     bool IsAccessorConstant() const { | 
 |  2510       return !IsTransition() && details_.type() == ACCESSOR_CONSTANT; | 
 |  2511     } | 
 |  2512     bool IsConfigurable() const { return details_.IsConfigurable(); } | 
 |  2513     bool IsReadOnly() const { return details_.IsReadOnly(); } | 
|  2621  |  2514  | 
|  2622     bool IsStringType() { return map_->instance_type() < FIRST_NONSTRING_TYPE; } |  2515     bool IsStringType() { return map_->instance_type() < FIRST_NONSTRING_TYPE; } | 
|  2623     bool IsNumberType() { return map_->instance_type() == HEAP_NUMBER_TYPE; } |  2516     bool IsNumberType() { return map_->instance_type() == HEAP_NUMBER_TYPE; } | 
|  2624     bool IsValueWrapped() { return IsStringType() || IsNumberType(); } |  2517     bool IsValueWrapped() { return IsStringType() || IsNumberType(); } | 
|  2625     bool IsArrayType() { return map_->instance_type() == JS_ARRAY_TYPE; } |  2518     bool IsArrayType() { return map_->instance_type() == JS_ARRAY_TYPE; } | 
|  2626  |  2519  | 
|  2627    private: |  2520    private: | 
 |  2521     Handle<Object> GetConstantFromMap(Handle<Map> map) const { | 
 |  2522       DCHECK_EQ(DESCRIPTOR_TYPE, lookup_type_); | 
 |  2523       DCHECK(number_ < map->NumberOfOwnDescriptors()); | 
 |  2524       return handle(map->instance_descriptors()->GetValue(number_), isolate()); | 
 |  2525     } | 
|  2628     Handle<Object> GetAccessorsFromMap(Handle<Map> map) const { |  2526     Handle<Object> GetAccessorsFromMap(Handle<Map> map) const { | 
|  2629       return handle(lookup_.GetValueFromMap(*map), isolate()); |  2527       return GetConstantFromMap(map); | 
|  2630     } |  | 
|  2631     Handle<Object> GetConstantFromMap(Handle<Map> map) const { |  | 
|  2632       return handle(lookup_.GetConstantFromMap(*map), isolate()); |  | 
|  2633     } |  2528     } | 
|  2634     Handle<HeapType> GetFieldTypeFromMap(Handle<Map> map) const { |  2529     Handle<HeapType> GetFieldTypeFromMap(Handle<Map> map) const { | 
|  2635       return handle(lookup_.GetFieldTypeFromMap(*map), isolate()); |  2530       DCHECK(IsFound()); | 
 |  2531       DCHECK(number_ < map->NumberOfOwnDescriptors()); | 
 |  2532       return handle(map->instance_descriptors()->GetFieldType(number_), | 
 |  2533                     isolate()); | 
|  2636     } |  2534     } | 
|  2637     Handle<Map> GetFieldOwnerFromMap(Handle<Map> map) const { |  2535     Handle<Map> GetFieldOwnerFromMap(Handle<Map> map) const { | 
|  2638       return handle(lookup_.GetFieldOwnerFromMap(*map)); |  2536       DCHECK(IsFound()); | 
 |  2537       DCHECK(number_ < map->NumberOfOwnDescriptors()); | 
 |  2538       return handle(map->FindFieldOwner(number_)); | 
|  2639     } |  2539     } | 
|  2640     int GetLocalFieldIndexFromMap(Handle<Map> map) const { |  2540     int GetLocalFieldIndexFromMap(Handle<Map> map) const { | 
|  2641       return lookup_.GetLocalFieldIndexFromMap(*map); |  2541       DCHECK(lookup_type_ == DESCRIPTOR_TYPE || | 
 |  2542              lookup_type_ == TRANSITION_TYPE); | 
 |  2543       DCHECK(number_ < map->NumberOfOwnDescriptors()); | 
 |  2544       int field_index = map->instance_descriptors()->GetFieldIndex(number_); | 
 |  2545       return field_index - map->inobject_properties(); | 
|  2642     } |  2546     } | 
|  2643     Representation representation() const { return lookup_.representation(); } |  2547  | 
 |  2548     void LookupDescriptor(Map* map, Name* name) { | 
 |  2549       DescriptorArray* descriptors = map->instance_descriptors(); | 
 |  2550       int number = descriptors->SearchWithCache(name, map); | 
 |  2551       if (number == DescriptorArray::kNotFound) return NotFound(); | 
 |  2552       lookup_type_ = DESCRIPTOR_TYPE; | 
 |  2553       details_ = descriptors->GetDetails(number); | 
 |  2554       number_ = number; | 
 |  2555     } | 
 |  2556     void LookupTransition(Map* map, Name* name, PropertyAttributes attributes) { | 
 |  2557       int transition_index = map->SearchTransition(kData, name, attributes); | 
 |  2558       if (transition_index == TransitionArray::kNotFound) return NotFound(); | 
 |  2559       lookup_type_ = TRANSITION_TYPE; | 
 |  2560       transition_ = handle(map->GetTransition(transition_index)); | 
 |  2561       number_ = transition_->LastAdded(); | 
 |  2562       details_ = transition_->instance_descriptors()->GetDetails(number_); | 
 |  2563     } | 
 |  2564     void NotFound() { | 
 |  2565       lookup_type_ = NOT_FOUND; | 
 |  2566       details_ = PropertyDetails(NONE, DATA, 0); | 
 |  2567     } | 
 |  2568     Representation representation() const { | 
 |  2569       DCHECK(IsFound()); | 
 |  2570       return details_.representation(); | 
 |  2571     } | 
 |  2572     bool IsTransitionToData() const { | 
 |  2573       return IsTransition() && details_.type() == DATA; | 
 |  2574     } | 
|  2644  |  2575  | 
|  2645     Zone* zone() { return builder_->zone(); } |  2576     Zone* zone() { return builder_->zone(); } | 
|  2646     CompilationInfo* top_info() { return builder_->top_info(); } |  2577     CompilationInfo* top_info() { return builder_->top_info(); } | 
|  2647     CompilationInfo* current_info() { return builder_->current_info(); } |  2578     CompilationInfo* current_info() { return builder_->current_info(); } | 
|  2648  |  2579  | 
|  2649     bool LoadResult(Handle<Map> map); |  2580     bool LoadResult(Handle<Map> map); | 
|  2650     void LoadFieldMaps(Handle<Map> map); |  2581     void LoadFieldMaps(Handle<Map> map); | 
|  2651     bool LookupDescriptor(); |  2582     bool LookupDescriptor(); | 
|  2652     bool LookupInPrototypes(); |  2583     bool LookupInPrototypes(); | 
|  2653     bool IsCompatible(PropertyAccessInfo* other); |  2584     bool IsCompatible(PropertyAccessInfo* other); | 
|  2654  |  2585  | 
|  2655     void GeneralizeRepresentation(Representation r) { |  2586     void GeneralizeRepresentation(Representation r) { | 
|  2656       access_ = access_.WithRepresentation( |  2587       access_ = access_.WithRepresentation( | 
|  2657           access_.representation().generalize(r)); |  2588           access_.representation().generalize(r)); | 
|  2658     } |  2589     } | 
|  2659  |  2590  | 
|  2660     LookupResult lookup_; |  | 
|  2661     HOptimizedGraphBuilder* builder_; |  2591     HOptimizedGraphBuilder* builder_; | 
|  2662     PropertyAccessType access_type_; |  2592     PropertyAccessType access_type_; | 
|  2663     Handle<Map> map_; |  2593     Handle<Map> map_; | 
|  2664     Handle<String> name_; |  2594     Handle<String> name_; | 
|  2665     Handle<JSObject> holder_; |  2595     Handle<JSObject> holder_; | 
|  2666     Handle<JSFunction> accessor_; |  2596     Handle<JSFunction> accessor_; | 
|  2667     Handle<JSObject> api_holder_; |  2597     Handle<JSObject> api_holder_; | 
|  2668     Handle<Object> constant_; |  2598     Handle<Object> constant_; | 
|  2669     SmallMapList field_maps_; |  2599     SmallMapList field_maps_; | 
|  2670     HType field_type_; |  2600     HType field_type_; | 
|  2671     HObjectAccess access_; |  2601     HObjectAccess access_; | 
 |  2602  | 
 |  2603     enum { NOT_FOUND, DESCRIPTOR_TYPE, TRANSITION_TYPE } lookup_type_; | 
 |  2604     Handle<Map> transition_; | 
 |  2605     int number_; | 
 |  2606     PropertyDetails details_; | 
|  2672   }; |  2607   }; | 
|  2673  |  2608  | 
|  2674   HInstruction* BuildMonomorphicAccess(PropertyAccessInfo* info, |  2609   HInstruction* BuildMonomorphicAccess(PropertyAccessInfo* info, | 
|  2675                                        HValue* object, |  2610                                        HValue* object, | 
|  2676                                        HValue* checked_object, |  2611                                        HValue* checked_object, | 
|  2677                                        HValue* value, |  2612                                        HValue* value, | 
|  2678                                        BailoutId ast_id, |  2613                                        BailoutId ast_id, | 
|  2679                                        BailoutId return_id, |  2614                                        BailoutId return_id, | 
|  2680                                        bool can_inline_accessor = true); |  2615                                        bool can_inline_accessor = true); | 
|  2681  |  2616  | 
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  3032   } |  2967   } | 
|  3033  |  2968  | 
|  3034  private: |  2969  private: | 
|  3035   HGraphBuilder* builder_; |  2970   HGraphBuilder* builder_; | 
|  3036 }; |  2971 }; | 
|  3037  |  2972  | 
|  3038  |  2973  | 
|  3039 } }  // namespace v8::internal |  2974 } }  // namespace v8::internal | 
|  3040  |  2975  | 
|  3041 #endif  // V8_HYDROGEN_H_ |  2976 #endif  // V8_HYDROGEN_H_ | 
| OLD | NEW |