summaryrefslogtreecommitdiffstats
path: root/chromium/v8/src/property.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/v8/src/property.h')
-rw-r--r--chromium/v8/src/property.h407
1 files changed, 201 insertions, 206 deletions
diff --git a/chromium/v8/src/property.h b/chromium/v8/src/property.h
index da772dc86c3..ebb43430a04 100644
--- a/chromium/v8/src/property.h
+++ b/chromium/v8/src/property.h
@@ -1,60 +1,35 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_PROPERTY_H_
#define V8_PROPERTY_H_
-#include "allocation.h"
-#include "transitions.h"
+#include "src/isolate.h"
+#include "src/factory.h"
+#include "src/field-index.h"
+#include "src/field-index-inl.h"
+#include "src/types.h"
namespace v8 {
namespace internal {
-
// Abstraction for elements in instance-descriptor arrays.
//
// Each descriptor has a key, property attributes, property type,
// property index (in the actual instance-descriptor array) and
// optionally a piece of data.
-//
-
class Descriptor BASE_EMBEDDED {
public:
- MUST_USE_RESULT MaybeObject* KeyToUniqueName() {
+ void KeyToUniqueName() {
if (!key_->IsUniqueName()) {
- MaybeObject* maybe_result =
- key_->GetIsolate()->heap()->InternalizeString(String::cast(key_));
- if (!maybe_result->To(&key_)) return maybe_result;
+ key_ = key_->GetIsolate()->factory()->InternalizeString(
+ Handle<String>::cast(key_));
}
- return key_;
}
- Name* GetKey() { return key_; }
- Object* GetValue() { return value_; }
+ Handle<Name> GetKey() { return key_; }
+ Handle<Object> GetValue() { return value_; }
PropertyDetails GetDetails() { return details_; }
#ifdef OBJECT_PRINT
@@ -64,26 +39,26 @@ class Descriptor BASE_EMBEDDED {
void SetSortedKeyIndex(int index) { details_ = details_.set_pointer(index); }
private:
- Name* key_;
- Object* value_;
+ Handle<Name> key_;
+ Handle<Object> value_;
PropertyDetails details_;
protected:
Descriptor() : details_(Smi::FromInt(0)) {}
- void Init(Name* key, Object* value, PropertyDetails details) {
+ void Init(Handle<Name> key, Handle<Object> value, PropertyDetails details) {
key_ = key;
value_ = value;
details_ = details;
}
- Descriptor(Name* key, Object* value, PropertyDetails details)
+ Descriptor(Handle<Name> key, Handle<Object> value, PropertyDetails details)
: key_(key),
value_(value),
details_(details) { }
- Descriptor(Name* key,
- Object* value,
+ Descriptor(Handle<Name> key,
+ Handle<Object> value,
PropertyAttributes attributes,
PropertyType type,
Representation representation,
@@ -93,91 +68,49 @@ class Descriptor BASE_EMBEDDED {
details_(attributes, type, representation, field_index) { }
friend class DescriptorArray;
+ friend class Map;
};
-class FieldDescriptor: public Descriptor {
+class FieldDescriptor V8_FINAL : public Descriptor {
public:
- FieldDescriptor(Name* key,
+ FieldDescriptor(Handle<Name> key,
int field_index,
PropertyAttributes attributes,
Representation representation)
- : Descriptor(key, Smi::FromInt(0), attributes,
+ : Descriptor(key, HeapType::Any(key->GetIsolate()), attributes,
FIELD, representation, field_index) {}
+ FieldDescriptor(Handle<Name> key,
+ int field_index,
+ Handle<HeapType> field_type,
+ PropertyAttributes attributes,
+ Representation representation)
+ : Descriptor(key, field_type, attributes, FIELD,
+ representation, field_index) { }
};
-class ConstantDescriptor: public Descriptor {
+class ConstantDescriptor V8_FINAL : public Descriptor {
public:
- ConstantDescriptor(Name* key,
- Object* value,
+ ConstantDescriptor(Handle<Name> key,
+ Handle<Object> value,
PropertyAttributes attributes)
: Descriptor(key, value, attributes, CONSTANT,
value->OptimalRepresentation()) {}
};
-class CallbacksDescriptor: public Descriptor {
+class CallbacksDescriptor V8_FINAL : public Descriptor {
public:
- CallbacksDescriptor(Name* key,
- Object* foreign,
+ CallbacksDescriptor(Handle<Name> key,
+ Handle<Object> foreign,
PropertyAttributes attributes)
: Descriptor(key, foreign, attributes, CALLBACKS,
Representation::Tagged()) {}
};
-// Holds a property index value distinguishing if it is a field index or an
-// index inside the object header.
-class PropertyIndex {
- public:
- static PropertyIndex NewFieldIndex(int index) {
- return PropertyIndex(index, false);
- }
- static PropertyIndex NewHeaderIndex(int index) {
- return PropertyIndex(index, true);
- }
-
- bool is_field_index() { return (index_ & kHeaderIndexBit) == 0; }
- bool is_header_index() { return (index_ & kHeaderIndexBit) != 0; }
-
- int field_index() {
- ASSERT(is_field_index());
- return value();
- }
- int header_index() {
- ASSERT(is_header_index());
- return value();
- }
-
- bool is_inobject(Handle<JSObject> holder) {
- if (is_header_index()) return true;
- return field_index() < holder->map()->inobject_properties();
- }
-
- int translate(Handle<JSObject> holder) {
- if (is_header_index()) return header_index();
- int index = field_index() - holder->map()->inobject_properties();
- if (index >= 0) return index;
- return index + holder->map()->instance_size() / kPointerSize;
- }
-
- private:
- static const int kHeaderIndexBit = 1 << 31;
- static const int kIndexMask = ~kHeaderIndexBit;
-
- int value() { return index_ & kIndexMask; }
-
- PropertyIndex(int index, bool is_header_based)
- : index_(index | (is_header_based ? kHeaderIndexBit : 0)) {
- ASSERT(index <= kIndexMask);
- }
-
- int index_;
-};
-
-
-class LookupResult BASE_EMBEDDED {
+class LookupResult V8_FINAL BASE_EMBEDDED {
public:
explicit LookupResult(Isolate* isolate)
: isolate_(isolate),
@@ -187,12 +120,12 @@ class LookupResult BASE_EMBEDDED {
transition_(NULL),
cacheable_(true),
details_(NONE, NONEXISTENT, Representation::None()) {
- isolate->SetTopLookupResult(this);
+ isolate->set_top_lookup_result(this);
}
~LookupResult() {
ASSERT(isolate()->top_lookup_result() == this);
- isolate()->SetTopLookupResult(next_);
+ isolate()->set_top_lookup_result(next_);
}
Isolate* isolate() const { return isolate_; }
@@ -200,23 +133,39 @@ class LookupResult BASE_EMBEDDED {
void DescriptorResult(JSObject* holder, PropertyDetails details, int number) {
lookup_type_ = DESCRIPTOR_TYPE;
holder_ = holder;
+ transition_ = NULL;
details_ = details;
number_ = number;
- transition_ = NULL;
}
- bool CanHoldValue(Handle<Object> value) {
- if (IsNormal()) return true;
- ASSERT(!IsTransition());
- return value->FitsRepresentation(details_.representation());
+ bool CanHoldValue(Handle<Object> value) const {
+ switch (type()) {
+ case NORMAL:
+ return true;
+ case FIELD:
+ return value->FitsRepresentation(representation()) &&
+ GetFieldType()->NowContains(value);
+ case CONSTANT:
+ ASSERT(GetConstant() != *value ||
+ value->FitsRepresentation(representation()));
+ return GetConstant() == *value;
+ case CALLBACKS:
+ case HANDLER:
+ case INTERCEPTOR:
+ return true;
+ case NONEXISTENT:
+ UNREACHABLE();
+ }
+ UNREACHABLE();
+ return true;
}
void TransitionResult(JSObject* holder, Map* target) {
lookup_type_ = TRANSITION_TYPE;
- details_ = PropertyDetails(NONE, TRANSITION, Representation::None());
+ number_ = target->LastAdded();
+ details_ = target->instance_descriptors()->GetDetails(number_);
holder_ = holder;
transition_ = target;
- number_ = 0xAAAA;
}
void DictionaryResult(JSObject* holder, int entry) {
@@ -246,200 +195,216 @@ class LookupResult BASE_EMBEDDED {
lookup_type_ = NOT_FOUND;
details_ = PropertyDetails(NONE, NONEXISTENT, Representation::None());
holder_ = NULL;
+ transition_ = NULL;
}
- JSObject* holder() {
+ JSObject* holder() const {
ASSERT(IsFound());
return JSObject::cast(holder_);
}
- JSProxy* proxy() {
+ JSProxy* proxy() const {
ASSERT(IsHandler());
return JSProxy::cast(holder_);
}
- PropertyType type() {
+ PropertyType type() const {
ASSERT(IsFound());
return details_.type();
}
- Representation representation() {
+ Representation representation() const {
ASSERT(IsFound());
- ASSERT(!IsTransition());
ASSERT(details_.type() != NONEXISTENT);
return details_.representation();
}
- PropertyAttributes GetAttributes() {
- ASSERT(!IsTransition());
+ PropertyAttributes GetAttributes() const {
ASSERT(IsFound());
ASSERT(details_.type() != NONEXISTENT);
return details_.attributes();
}
- PropertyDetails GetPropertyDetails() {
- ASSERT(!IsTransition());
+ PropertyDetails GetPropertyDetails() const {
return details_;
}
- bool IsFastPropertyType() {
+ bool IsFastPropertyType() const {
ASSERT(IsFound());
return IsTransition() || type() != NORMAL;
}
// Property callbacks does not include transitions to callbacks.
- bool IsPropertyCallbacks() {
+ bool IsPropertyCallbacks() const {
ASSERT(!(details_.type() == CALLBACKS && !IsFound()));
- return details_.type() == CALLBACKS;
+ return !IsTransition() && details_.type() == CALLBACKS;
}
- bool IsReadOnly() {
+ bool IsReadOnly() const {
ASSERT(IsFound());
- ASSERT(!IsTransition());
ASSERT(details_.type() != NONEXISTENT);
return details_.IsReadOnly();
}
- bool IsField() {
+ bool IsField() const {
ASSERT(!(details_.type() == FIELD && !IsFound()));
- return details_.type() == FIELD;
+ return IsDescriptorOrDictionary() && type() == FIELD;
}
- bool IsNormal() {
+ bool IsNormal() const {
ASSERT(!(details_.type() == NORMAL && !IsFound()));
- return details_.type() == NORMAL;
+ return IsDescriptorOrDictionary() && type() == NORMAL;
}
- bool IsConstant() {
+ bool IsConstant() const {
ASSERT(!(details_.type() == CONSTANT && !IsFound()));
- return details_.type() == CONSTANT;
+ return IsDescriptorOrDictionary() && type() == CONSTANT;
}
- bool IsConstantFunction() {
- return IsConstant() && GetValue()->IsJSFunction();
+ bool IsConstantFunction() const {
+ return IsConstant() && GetConstant()->IsJSFunction();
}
- bool IsDontDelete() { return details_.IsDontDelete(); }
- bool IsDontEnum() { return details_.IsDontEnum(); }
- bool IsFound() { return lookup_type_ != NOT_FOUND; }
- bool IsTransition() { return lookup_type_ == TRANSITION_TYPE; }
- bool IsHandler() { return lookup_type_ == HANDLER_TYPE; }
- bool IsInterceptor() { return lookup_type_ == INTERCEPTOR_TYPE; }
+ bool IsDontDelete() const { return details_.IsDontDelete(); }
+ bool IsDontEnum() const { return details_.IsDontEnum(); }
+ bool IsFound() const { return lookup_type_ != NOT_FOUND; }
+ bool IsDescriptorOrDictionary() const {
+ return lookup_type_ == DESCRIPTOR_TYPE || lookup_type_ == DICTIONARY_TYPE;
+ }
+ bool IsTransition() const { return lookup_type_ == TRANSITION_TYPE; }
+ bool IsHandler() const { return lookup_type_ == HANDLER_TYPE; }
+ bool IsInterceptor() const { return lookup_type_ == INTERCEPTOR_TYPE; }
// Is the result is a property excluding transitions and the null descriptor?
- bool IsProperty() {
+ bool IsProperty() const {
return IsFound() && !IsTransition();
}
- bool IsDataProperty() {
- switch (type()) {
- case FIELD:
- case NORMAL:
- case CONSTANT:
- return true;
- case CALLBACKS: {
- Object* callback = GetCallbackObject();
- return callback->IsAccessorInfo() || callback->IsForeign();
- }
- case HANDLER:
- case INTERCEPTOR:
- case TRANSITION:
- case NONEXISTENT:
+ bool IsDataProperty() const {
+ switch (lookup_type_) {
+ case NOT_FOUND:
+ case TRANSITION_TYPE:
+ case HANDLER_TYPE:
+ case INTERCEPTOR_TYPE:
return false;
+
+ case DESCRIPTOR_TYPE:
+ case DICTIONARY_TYPE:
+ switch (type()) {
+ case FIELD:
+ case NORMAL:
+ case CONSTANT:
+ return true;
+ case CALLBACKS: {
+ Object* callback = GetCallbackObject();
+ ASSERT(!callback->IsForeign());
+ return callback->IsAccessorInfo();
+ }
+ case HANDLER:
+ case INTERCEPTOR:
+ case NONEXISTENT:
+ UNREACHABLE();
+ return false;
+ }
}
UNREACHABLE();
return false;
}
- bool IsCacheable() { return cacheable_; }
+ bool IsCacheable() const { return cacheable_; }
void DisallowCaching() { cacheable_ = false; }
- Object* GetLazyValue() {
- switch (type()) {
- case FIELD:
- return holder()->RawFastPropertyAt(GetFieldIndex().field_index());
- case NORMAL: {
- Object* value;
- value = holder()->property_dictionary()->ValueAt(GetDictionaryEntry());
- if (holder()->IsGlobalObject()) {
- value = PropertyCell::cast(value)->value();
- }
- return value;
- }
- case CONSTANT:
- return GetConstant();
- case CALLBACKS:
- case HANDLER:
- case INTERCEPTOR:
- case TRANSITION:
- case NONEXISTENT:
+ Object* GetLazyValue() const {
+ switch (lookup_type_) {
+ case NOT_FOUND:
+ case TRANSITION_TYPE:
+ case HANDLER_TYPE:
+ case INTERCEPTOR_TYPE:
return isolate()->heap()->the_hole_value();
+
+ case DESCRIPTOR_TYPE:
+ case DICTIONARY_TYPE:
+ switch (type()) {
+ case FIELD:
+ return holder()->RawFastPropertyAt(GetFieldIndex());
+ case NORMAL: {
+ Object* value = holder()->property_dictionary()->ValueAt(
+ GetDictionaryEntry());
+ if (holder()->IsGlobalObject()) {
+ value = PropertyCell::cast(value)->value();
+ }
+ return value;
+ }
+ case CONSTANT:
+ return GetConstant();
+ case CALLBACKS:
+ return isolate()->heap()->the_hole_value();
+ case HANDLER:
+ case INTERCEPTOR:
+ case NONEXISTENT:
+ UNREACHABLE();
+ return NULL;
+ }
}
UNREACHABLE();
return NULL;
}
- Map* GetTransitionTarget() {
+ Map* GetTransitionTarget() const {
+ ASSERT(IsTransition());
return transition_;
}
- PropertyDetails GetTransitionDetails() {
- return transition_->GetLastDescriptorDetails();
+ bool IsTransitionToField() const {
+ return IsTransition() && details_.type() == FIELD;
}
- bool IsTransitionToField() {
- return IsTransition() && GetTransitionDetails().type() == FIELD;
+ bool IsTransitionToConstant() const {
+ return IsTransition() && details_.type() == CONSTANT;
}
- bool IsTransitionToConstant() {
- return IsTransition() && GetTransitionDetails().type() == CONSTANT;
- }
-
- int GetTransitionIndex() {
- ASSERT(IsTransition());
- return number_;
- }
-
- int GetDescriptorIndex() {
+ int GetDescriptorIndex() const {
ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
return number_;
}
- PropertyIndex GetFieldIndex() {
- ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
- return PropertyIndex::NewFieldIndex(GetFieldIndexFromMap(holder()->map()));
+ FieldIndex GetFieldIndex() const {
+ ASSERT(lookup_type_ == DESCRIPTOR_TYPE ||
+ lookup_type_ == TRANSITION_TYPE);
+ return FieldIndex::ForLookupResult(this);
}
- int GetLocalFieldIndexFromMap(Map* map) {
+ int GetLocalFieldIndexFromMap(Map* map) const {
return GetFieldIndexFromMap(map) - map->inobject_properties();
}
- int GetDictionaryEntry() {
+ int GetDictionaryEntry() const {
ASSERT(lookup_type_ == DICTIONARY_TYPE);
return number_;
}
- JSFunction* GetConstantFunction() {
+ JSFunction* GetConstantFunction() const {
ASSERT(type() == CONSTANT);
return JSFunction::cast(GetValue());
}
- Object* GetConstantFromMap(Map* map) {
+ Object* GetConstantFromMap(Map* map) const {
ASSERT(type() == CONSTANT);
return GetValueFromMap(map);
}
- JSFunction* GetConstantFunctionFromMap(Map* map) {
+ JSFunction* GetConstantFunctionFromMap(Map* map) const {
return JSFunction::cast(GetConstantFromMap(map));
}
- Object* GetConstant() {
+ Object* GetConstant() const {
ASSERT(type() == CONSTANT);
return GetValue();
}
- Object* GetCallbackObject() {
- ASSERT(type() == CALLBACKS && !IsTransition());
+ Object* GetCallbackObject() const {
+ ASSERT(!IsTransition());
+ ASSERT(type() == CALLBACKS);
return GetValue();
}
@@ -447,9 +412,11 @@ class LookupResult BASE_EMBEDDED {
void Print(FILE* out);
#endif
- Object* GetValue() {
+ Object* GetValue() const {
if (lookup_type_ == DESCRIPTOR_TYPE) {
return GetValueFromMap(holder()->map());
+ } else if (lookup_type_ == TRANSITION_TYPE) {
+ return GetValueFromMap(transition_);
}
// In the dictionary case, the data is held in the value field.
ASSERT(lookup_type_ == DICTIONARY_TYPE);
@@ -457,17 +424,46 @@ class LookupResult BASE_EMBEDDED {
}
Object* GetValueFromMap(Map* map) const {
- ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
+ ASSERT(lookup_type_ == DESCRIPTOR_TYPE ||
+ lookup_type_ == TRANSITION_TYPE);
ASSERT(number_ < map->NumberOfOwnDescriptors());
return map->instance_descriptors()->GetValue(number_);
}
int GetFieldIndexFromMap(Map* map) const {
- ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
+ ASSERT(lookup_type_ == DESCRIPTOR_TYPE ||
+ lookup_type_ == TRANSITION_TYPE);
ASSERT(number_ < map->NumberOfOwnDescriptors());
return map->instance_descriptors()->GetFieldIndex(number_);
}
+ HeapType* GetFieldType() const {
+ ASSERT(type() == FIELD);
+ if (lookup_type_ == DESCRIPTOR_TYPE) {
+ return GetFieldTypeFromMap(holder()->map());
+ }
+ ASSERT(lookup_type_ == TRANSITION_TYPE);
+ return GetFieldTypeFromMap(transition_);
+ }
+
+ HeapType* GetFieldTypeFromMap(Map* map) const {
+ ASSERT(lookup_type_ == DESCRIPTOR_TYPE ||
+ lookup_type_ == TRANSITION_TYPE);
+ ASSERT(number_ < map->NumberOfOwnDescriptors());
+ return map->instance_descriptors()->GetFieldType(number_);
+ }
+
+ Map* GetFieldOwner() const {
+ return GetFieldOwnerFromMap(holder()->map());
+ }
+
+ Map* GetFieldOwnerFromMap(Map* map) const {
+ ASSERT(lookup_type_ == DESCRIPTOR_TYPE ||
+ lookup_type_ == TRANSITION_TYPE);
+ ASSERT(number_ < map->NumberOfOwnDescriptors());
+ return map->FindFieldOwner(number_);
+ }
+
void Iterate(ObjectVisitor* visitor);
private:
@@ -491,7 +487,6 @@ class LookupResult BASE_EMBEDDED {
PropertyDetails details_;
};
-
} } // namespace v8::internal
#endif // V8_PROPERTY_H_