Index: src/hydrogen.h |
diff --git a/src/hydrogen.h b/src/hydrogen.h |
index 870c4908bdb2b8f99ee9c8bbc9e633cfd272c737..8411b6ddf9e9f5967fae701c48118d42b4be6020 100644 |
--- a/src/hydrogen.h |
+++ b/src/hydrogen.h |
@@ -2361,6 +2361,7 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { |
int argc, |
BailoutId ast_id, |
ApiCallType call_type); |
+ static bool IsReadOnlyLengthDescriptor(Handle<Map> jsarray_map); |
static bool CanInlineArrayResizeOperation(Handle<Map> receiver_map); |
// If --trace-inlining, print a line of the inlining trace. Inlining |
@@ -2429,13 +2430,127 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { |
void BuildInlinedCallArray(Expression* expression, int argument_count, |
Handle<AllocationSite> site); |
+ class LookupResult FINAL BASE_EMBEDDED { |
+ public: |
+ LookupResult() |
+ : lookup_type_(NOT_FOUND), |
+ details_(NONE, DATA, Representation::None()) {} |
+ |
+ void LookupDescriptor(Map* map, Name* name) { |
+ DescriptorArray* descriptors = map->instance_descriptors(); |
+ int number = descriptors->SearchWithCache(name, map); |
+ if (number == DescriptorArray::kNotFound) return NotFound(); |
+ lookup_type_ = DESCRIPTOR_TYPE; |
+ details_ = descriptors->GetDetails(number); |
+ number_ = number; |
+ } |
+ |
+ void LookupTransition(Map* map, Name* name, PropertyAttributes attributes) { |
+ int transition_index = map->SearchTransition(kData, name, attributes); |
+ if (transition_index == TransitionArray::kNotFound) return NotFound(); |
+ lookup_type_ = TRANSITION_TYPE; |
+ transition_ = handle(map->GetTransition(transition_index)); |
+ number_ = transition_->LastAdded(); |
+ details_ = transition_->instance_descriptors()->GetDetails(number_); |
+ } |
+ |
+ void NotFound() { |
+ lookup_type_ = NOT_FOUND; |
+ details_ = PropertyDetails(NONE, DATA, 0); |
+ } |
+ |
+ Representation representation() const { |
+ DCHECK(IsFound()); |
+ return details_.representation(); |
+ } |
+ |
+ // Property callbacks does not include transitions to callbacks. |
+ bool IsAccessorConstant() const { |
+ return !IsTransition() && details_.type() == ACCESSOR_CONSTANT; |
+ } |
+ |
+ bool IsReadOnly() const { |
+ DCHECK(IsFound()); |
+ return details_.IsReadOnly(); |
+ } |
+ |
+ bool IsData() const { |
+ return lookup_type_ == DESCRIPTOR_TYPE && details_.type() == DATA; |
+ } |
+ |
+ bool IsDataConstant() const { |
+ return lookup_type_ == DESCRIPTOR_TYPE && |
+ details_.type() == DATA_CONSTANT; |
+ } |
+ |
+ bool IsConfigurable() const { return details_.IsConfigurable(); } |
+ bool IsFound() const { return lookup_type_ != NOT_FOUND; } |
+ bool IsTransition() const { return lookup_type_ == TRANSITION_TYPE; } |
+ |
+ // Is the result is a property excluding transitions and the null |
+ // descriptor? |
+ bool IsProperty() const { return IsFound() && !IsTransition(); } |
+ |
+ Handle<Map> GetTransitionTarget() const { |
+ DCHECK(IsTransition()); |
+ return transition_; |
+ } |
+ |
+ bool IsTransitionToData() const { |
+ return IsTransition() && details_.type() == DATA; |
+ } |
+ |
+ int GetLocalFieldIndexFromMap(Map* map) const { |
+ return GetFieldIndexFromMap(map) - map->inobject_properties(); |
+ } |
+ |
+ Object* GetConstantFromMap(Map* map) const { |
+ DCHECK(details_.type() == DATA_CONSTANT); |
+ return GetValueFromMap(map); |
+ } |
+ |
+ Object* GetValueFromMap(Map* map) const { |
+ DCHECK(lookup_type_ == DESCRIPTOR_TYPE || |
+ lookup_type_ == TRANSITION_TYPE); |
+ DCHECK(number_ < map->NumberOfOwnDescriptors()); |
+ return map->instance_descriptors()->GetValue(number_); |
+ } |
+ |
+ int GetFieldIndexFromMap(Map* map) const { |
+ DCHECK(lookup_type_ == DESCRIPTOR_TYPE || |
+ lookup_type_ == TRANSITION_TYPE); |
+ DCHECK(number_ < map->NumberOfOwnDescriptors()); |
+ return map->instance_descriptors()->GetFieldIndex(number_); |
+ } |
+ |
+ HeapType* GetFieldTypeFromMap(Map* map) const { |
+ DCHECK_NE(NOT_FOUND, lookup_type_); |
+ DCHECK(number_ < map->NumberOfOwnDescriptors()); |
+ return map->instance_descriptors()->GetFieldType(number_); |
+ } |
+ |
+ Map* GetFieldOwnerFromMap(Map* map) const { |
+ DCHECK(lookup_type_ == DESCRIPTOR_TYPE || |
+ lookup_type_ == TRANSITION_TYPE); |
+ DCHECK(number_ < map->NumberOfOwnDescriptors()); |
+ return map->FindFieldOwner(number_); |
+ } |
+ |
+ private: |
+ // Where did we find the result; |
+ enum { NOT_FOUND, DESCRIPTOR_TYPE, TRANSITION_TYPE } lookup_type_; |
+ |
+ Handle<Map> transition_; |
+ int number_; |
+ PropertyDetails details_; |
+ }; |
+ |
class PropertyAccessInfo { |
public: |
PropertyAccessInfo(HOptimizedGraphBuilder* builder, |
PropertyAccessType access_type, Handle<Map> map, |
Handle<String> name) |
- : lookup_(builder->isolate()), |
- builder_(builder), |
+ : builder_(builder), |
access_type_(access_type), |
map_(map), |
name_(name), |
@@ -2485,11 +2600,11 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor { |
bool has_holder() { return !holder_.is_null(); } |
bool IsLoad() const { return access_type_ == LOAD; } |
- Isolate* isolate() const { return lookup_.isolate(); } |
+ Isolate* isolate() const { return builder_->isolate(); } |
Handle<JSObject> holder() { return holder_; } |
Handle<JSFunction> accessor() { return accessor_; } |
Handle<Object> constant() { return constant_; } |
- Handle<Map> transition() { return handle(lookup_.GetTransitionTarget()); } |
+ Handle<Map> transition() { return lookup_.GetTransitionTarget(); } |
SmallMapList* field_maps() { return &field_maps_; } |
HType field_type() const { return field_type_; } |
HObjectAccess access() { return access_; } |