summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/v8/src/property.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/v8/src/property.h')
-rw-r--r--src/3rdparty/v8/src/property.h179
1 files changed, 97 insertions, 82 deletions
diff --git a/src/3rdparty/v8/src/property.h b/src/3rdparty/v8/src/property.h
index ba5e3c8..3faa28b 100644
--- a/src/3rdparty/v8/src/property.h
+++ b/src/3rdparty/v8/src/property.h
@@ -29,6 +29,7 @@
#define V8_PROPERTY_H_
#include "allocation.h"
+#include "transitions.h"
namespace v8 {
namespace internal {
@@ -64,11 +65,10 @@ class Descriptor BASE_EMBEDDED {
#endif
void SetEnumerationIndex(int index) {
- ASSERT(PropertyDetails::IsValidIndex(index));
details_ = PropertyDetails(details_.attributes(), details_.type(), index);
}
- bool ContainsTransition();
+ void SetSortedKeyIndex(int index) { details_ = details_.set_pointer(index); }
private:
String* key_;
@@ -93,7 +93,7 @@ class Descriptor BASE_EMBEDDED {
Object* value,
PropertyAttributes attributes,
PropertyType type,
- int index = 0)
+ int index)
: key_(key),
value_(value),
details_(attributes, type, index) { }
@@ -101,35 +101,6 @@ class Descriptor BASE_EMBEDDED {
friend class DescriptorArray;
};
-// A pointer from a map to the new map that is created by adding
-// a named property. These are key to the speed and functioning of V8.
-// The two maps should always have the same prototype, since
-// MapSpace::CreateBackPointers depends on this.
-class MapTransitionDescriptor: public Descriptor {
- public:
- MapTransitionDescriptor(String* key, Map* map, PropertyAttributes attributes)
- : Descriptor(key, map, attributes, MAP_TRANSITION) { }
-};
-
-class ElementsTransitionDescriptor: public Descriptor {
- public:
- ElementsTransitionDescriptor(String* key,
- Object* map_or_array)
- : Descriptor(key, map_or_array, PropertyDetails(NONE,
- ELEMENTS_TRANSITION)) { }
-};
-
-// Marks a field name in a map so that adding the field is guaranteed
-// to create a FIELD descriptor in the new map. Used after adding
-// a constant function the first time, creating a CONSTANT_FUNCTION
-// descriptor in the new map. This avoids creating multiple maps with
-// the same CONSTANT_FUNCTION field.
-class ConstTransitionDescriptor: public Descriptor {
- public:
- explicit ConstTransitionDescriptor(String* key, Map* map)
- : Descriptor(key, map, NONE, CONSTANT_TRANSITION) { }
-};
-
class FieldDescriptor: public Descriptor {
public:
@@ -146,7 +117,7 @@ class ConstantFunctionDescriptor: public Descriptor {
ConstantFunctionDescriptor(String* key,
JSFunction* function,
PropertyAttributes attributes,
- int index = 0)
+ int index)
: Descriptor(key, function, attributes, CONSTANT_FUNCTION, index) {}
};
@@ -161,35 +132,6 @@ class CallbacksDescriptor: public Descriptor {
};
-template <class T>
-bool IsPropertyDescriptor(T* desc) {
- switch (desc->type()) {
- case NORMAL:
- case FIELD:
- case CONSTANT_FUNCTION:
- case HANDLER:
- case INTERCEPTOR:
- return true;
- case CALLBACKS: {
- Object* callback_object = desc->GetCallbackObject();
- // Non-JavaScript (i.e. native) accessors are always a property, otherwise
- // either the getter or the setter must be an accessor. Put another way:
- // If we only see map transitions and holes in a pair, this is not a
- // property.
- return (!callback_object->IsAccessorPair() ||
- AccessorPair::cast(callback_object)->ContainsAccessor());
- }
- case MAP_TRANSITION:
- case ELEMENTS_TRANSITION:
- case CONSTANT_TRANSITION:
- case NULL_DESCRIPTOR:
- return false;
- }
- UNREACHABLE(); // keep the compiler happy
- return false;
-}
-
-
class LookupResult BASE_EMBEDDED {
public:
explicit LookupResult(Isolate* isolate)
@@ -198,7 +140,7 @@ class LookupResult BASE_EMBEDDED {
lookup_type_(NOT_FOUND),
holder_(NULL),
cacheable_(true),
- details_(NONE, NORMAL) {
+ details_(NONE, NONEXISTENT) {
isolate->SetTopLookupResult(this);
}
@@ -214,6 +156,13 @@ class LookupResult BASE_EMBEDDED {
number_ = number;
}
+ void TransitionResult(JSObject* holder, int number) {
+ lookup_type_ = TRANSITION_TYPE;
+ details_ = PropertyDetails(NONE, TRANSITION);
+ holder_ = holder;
+ number_ = number;
+ }
+
void ConstantResult(JSObject* holder) {
lookup_type_ = CONSTANT_TYPE;
holder_ = holder;
@@ -246,6 +195,7 @@ class LookupResult BASE_EMBEDDED {
void NotFound() {
lookup_type_ = NOT_FOUND;
+ details_ = PropertyDetails(NONE, NONEXISTENT);
holder_ = NULL;
}
@@ -265,24 +215,61 @@ class LookupResult BASE_EMBEDDED {
}
PropertyAttributes GetAttributes() {
+ ASSERT(!IsTransition());
ASSERT(IsFound());
+ ASSERT(details_.type() != NONEXISTENT);
return details_.attributes();
}
PropertyDetails GetPropertyDetails() {
+ ASSERT(!IsTransition());
return details_;
}
- bool IsReadOnly() { return details_.IsReadOnly(); }
+ bool IsFastPropertyType() {
+ ASSERT(IsFound());
+ return IsTransition() || type() != NORMAL;
+ }
+
+ // Property callbacks does not include transitions to callbacks.
+ bool IsPropertyCallbacks() {
+ ASSERT(!(details_.type() == CALLBACKS && !IsFound()));
+ return details_.type() == CALLBACKS;
+ }
+
+ bool IsReadOnly() {
+ ASSERT(IsFound());
+ ASSERT(!IsTransition());
+ ASSERT(details_.type() != NONEXISTENT);
+ return details_.IsReadOnly();
+ }
+
+ bool IsField() {
+ ASSERT(!(details_.type() == FIELD && !IsFound()));
+ return details_.type() == FIELD;
+ }
+
+ bool IsNormal() {
+ ASSERT(!(details_.type() == NORMAL && !IsFound()));
+ return details_.type() == NORMAL;
+ }
+
+ bool IsConstantFunction() {
+ ASSERT(!(details_.type() == CONSTANT_FUNCTION && !IsFound()));
+ return details_.type() == CONSTANT_FUNCTION;
+ }
+
bool IsDontDelete() { return details_.IsDontDelete(); }
bool IsDontEnum() { return details_.IsDontEnum(); }
bool IsDeleted() { return details_.IsDeleted(); }
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; }
// Is the result is a property excluding transitions and the null descriptor?
bool IsProperty() {
- return IsFound() && IsPropertyDescriptor(this);
+ return IsFound() && !IsTransition();
}
bool IsCacheable() { return cacheable_; }
@@ -303,36 +290,59 @@ class LookupResult BASE_EMBEDDED {
case CONSTANT_FUNCTION:
return GetConstantFunction();
default:
- return Smi::FromInt(0);
+ return Isolate::Current()->heap()->the_hole_value();
}
}
+ Map* GetTransitionTarget() {
+ ASSERT(IsTransition());
+ TransitionArray* transitions = holder()->map()->transitions();
+ return transitions->GetTarget(number_);
+ }
+
+ PropertyDetails GetTransitionDetails(Map* map) {
+ ASSERT(IsTransition());
+ TransitionArray* transitions = map->transitions();
+ return transitions->GetTargetDetails(number_);
+ }
+
+ PropertyDetails GetTransitionDetails() {
+ return GetTransitionDetails(holder()->map());
+ }
+
+ bool IsTransitionToField(Map* map) {
+ return IsTransition() && GetTransitionDetails(map).type() == FIELD;
+ }
Map* GetTransitionMap() {
- ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
- ASSERT(type() == MAP_TRANSITION ||
- type() == ELEMENTS_TRANSITION ||
- type() == CONSTANT_TRANSITION);
+ ASSERT(IsTransition());
return Map::cast(GetValue());
}
Map* GetTransitionMapFromMap(Map* map) {
+ ASSERT(IsTransition());
+ return map->transitions()->GetTarget(number_);
+ }
+
+ int GetTransitionIndex() {
+ ASSERT(IsTransition());
+ return number_;
+ }
+
+ int GetDescriptorIndex() {
ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
- ASSERT(type() == MAP_TRANSITION);
- return Map::cast(map->instance_descriptors()->GetValue(number_));
+ return number_;
}
int GetFieldIndex() {
ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
- ASSERT(type() == FIELD);
+ ASSERT(IsField());
return Descriptor::IndexFromValue(GetValue());
}
int GetLocalFieldIndexFromMap(Map* map) {
- ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
- ASSERT(type() == FIELD);
- return Descriptor::IndexFromValue(
- map->instance_descriptors()->GetValue(number_)) -
+ ASSERT(IsField());
+ return Descriptor::IndexFromValue(GetValueFromMap(map)) -
map->inobject_properties();
}
@@ -347,16 +357,15 @@ class LookupResult BASE_EMBEDDED {
}
JSFunction* GetConstantFunctionFromMap(Map* map) {
- ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
ASSERT(type() == CONSTANT_FUNCTION);
- return JSFunction::cast(map->instance_descriptors()->GetValue(number_));
+ return JSFunction::cast(GetValueFromMap(map));
}
Object* GetCallbackObject() {
if (lookup_type_ == CONSTANT_TYPE) {
- // For now we only have the __proto__ as constant type.
return HEAP->prototype_accessors();
}
+ ASSERT(!IsTransition());
return GetValue();
}
@@ -366,14 +375,19 @@ class LookupResult BASE_EMBEDDED {
Object* GetValue() {
if (lookup_type_ == DESCRIPTOR_TYPE) {
- DescriptorArray* descriptors = holder()->map()->instance_descriptors();
- return descriptors->GetValue(number_);
+ return GetValueFromMap(holder()->map());
}
// In the dictionary case, the data is held in the value field.
ASSERT(lookup_type_ == DICTIONARY_TYPE);
return holder()->GetNormalizedProperty(this);
}
+ Object* GetValueFromMap(Map* map) const {
+ ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
+ ASSERT(number_ < map->NumberOfOwnDescriptors());
+ return map->instance_descriptors()->GetValue(number_);
+ }
+
void Iterate(ObjectVisitor* visitor);
private:
@@ -384,6 +398,7 @@ class LookupResult BASE_EMBEDDED {
enum {
NOT_FOUND,
DESCRIPTOR_TYPE,
+ TRANSITION_TYPE,
DICTIONARY_TYPE,
HANDLER_TYPE,
INTERCEPTOR_TYPE,