Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(27)

Unified Diff: src/property.h

Issue 10697015: Separating transitions from descriptors. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Using WhitenessWitness in TransitionArray code. Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/profile-generator.cc ('k') | src/property.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/property.h
diff --git a/src/property.h b/src/property.h
index 76ae0fbae1278e8ec420d28c27450430da4e87d6..53c344191ae66ce5d38615ab6c75660c93d21450 100644
--- a/src/property.h
+++ b/src/property.h
@@ -29,6 +29,7 @@
#define V8_PROPERTY_H_
#include "allocation.h"
+#include "transitions.h"
namespace v8 {
namespace internal {
@@ -68,8 +69,6 @@ class Descriptor BASE_EMBEDDED {
details_ = PropertyDetails(details_.attributes(), details_.type(), index);
}
- bool ContainsTransition();
-
private:
String* key_;
Object* value_;
@@ -101,27 +100,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) { }
-};
-
-// 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:
@@ -153,36 +131,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 CONSTANT_TRANSITION:
- return false;
- case NONEXISTENT:
- UNREACHABLE();
- break;
- }
- UNREACHABLE(); // keep the compiler happy
- return false;
-}
-
-
class LookupResult BASE_EMBEDDED {
public:
explicit LookupResult(Isolate* isolate)
@@ -207,6 +155,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;
@@ -259,27 +214,39 @@ class LookupResult BASE_EMBEDDED {
}
PropertyAttributes GetAttributes() {
+ ASSERT(!IsTransition());
ASSERT(IsFound());
+ ASSERT(details_.type() != NONEXISTENT);
return details_.attributes();
}
PropertyDetails GetPropertyDetails() {
+ ASSERT(!IsTransition());
return details_;
}
bool IsFastPropertyType() {
ASSERT(IsFound());
- return type() != NORMAL;
+ return IsTransition() || type() != NORMAL;
}
- bool IsReadOnly() {
- ASSERT(IsFound());
- return details_.IsReadOnly();
+ // Property callbacks does not include transitions to callbacks.
+ bool IsPropertyCallbacks() {
+ ASSERT(!(details_.type() == CALLBACKS && !IsFound()));
+ return details_.type() == CALLBACKS;
}
+ // Is callbacks contains both property callbacks and transitions to callbacks.
bool IsCallbacks() {
- ASSERT(!(details_.type() == CALLBACKS && !IsFound()));
- return details_.type() == CALLBACKS;
+ return IsPropertyCallbacks() ||
+ (IsTransition() && GetTransitionValue()->IsAccessorPair());
+ }
+
+ bool IsReadOnly() {
+ ASSERT(IsFound());
+ ASSERT(!IsTransition());
+ ASSERT(details_.type() != NONEXISTENT);
+ return details_.IsReadOnly();
}
bool IsField() {
@@ -297,21 +264,17 @@ class LookupResult BASE_EMBEDDED {
return details_.type() == CONSTANT_FUNCTION;
}
- bool IsMapTransition() {
- ASSERT(!(details_.type() == MAP_TRANSITION && !IsFound()));
- return details_.type() == MAP_TRANSITION;
- }
-
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_; }
@@ -336,17 +299,35 @@ class LookupResult BASE_EMBEDDED {
}
}
+ Object* GetTransitionValue() {
+ ASSERT(IsTransition());
+ TransitionArray* transitions = holder()->map()->transitions();
+ Object* value = transitions->GetValue(number_);
+ return value;
+ }
+
+ 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() == CONSTANT_TRANSITION);
+ ASSERT(IsTransition());
return Map::cast(GetValue());
}
Map* GetTransitionMapFromMap(Map* map) {
- ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
- ASSERT(type() == MAP_TRANSITION);
- return Map::cast(map->instance_descriptors()->GetValue(number_));
+ ASSERT(IsTransition());
+ return Map::cast(map->transitions()->GetValue(number_));
}
int GetFieldIndex() {
@@ -380,11 +361,14 @@ class LookupResult BASE_EMBEDDED {
}
Object* GetCallbackObject() {
- if (lookup_type_ == CONSTANT_TYPE) {
- // For now we only have the __proto__ as constant type.
- return HEAP->prototype_accessors();
+ switch (lookup_type_) {
+ case CONSTANT_TYPE:
+ return HEAP->prototype_accessors();
+ case TRANSITION_TYPE:
+ return GetTransitionValue();
+ default:
+ return GetValue();
}
- return GetValue();
}
#ifdef OBJECT_PRINT
@@ -411,6 +395,7 @@ class LookupResult BASE_EMBEDDED {
enum {
NOT_FOUND,
DESCRIPTOR_TYPE,
+ TRANSITION_TYPE,
DICTIONARY_TYPE,
HANDLER_TYPE,
INTERCEPTOR_TYPE,
« no previous file with comments | « src/profile-generator.cc ('k') | src/property.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698