Handlefy Descriptor and other code in objects.cc

R=verwaest@chromium.org

Review URL: https://codereview.chromium.org/228333003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20628 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 1b841f36
This diff is collapsed.
...@@ -1419,13 +1419,14 @@ class DictionaryElementsAccessor ...@@ -1419,13 +1419,14 @@ class DictionaryElementsAccessor
// Adjusts the length of the dictionary backing store and returns the new // Adjusts the length of the dictionary backing store and returns the new
// length according to ES5 section 15.4.5.2 behavior. // length according to ES5 section 15.4.5.2 behavior.
MUST_USE_RESULT static MaybeObject* SetLengthWithoutNormalize( static Handle<Object> SetLengthWithoutNormalize(
FixedArrayBase* store, Handle<FixedArrayBase> store,
JSArray* array, Handle<JSArray> array,
Object* length_object, Handle<Object> length_object,
uint32_t length) { uint32_t length) {
SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); Handle<SeededNumberDictionary> dict =
Heap* heap = array->GetHeap(); Handle<SeededNumberDictionary>::cast(store);
Isolate* isolate = array->GetIsolate();
int capacity = dict->Capacity(); int capacity = dict->Capacity();
uint32_t new_length = length; uint32_t new_length = length;
uint32_t old_length = static_cast<uint32_t>(array->length()->Number()); uint32_t old_length = static_cast<uint32_t>(array->length()->Number());
...@@ -1433,6 +1434,7 @@ class DictionaryElementsAccessor ...@@ -1433,6 +1434,7 @@ class DictionaryElementsAccessor
// Find last non-deletable element in range of elements to be // Find last non-deletable element in range of elements to be
// deleted and adjust range accordingly. // deleted and adjust range accordingly.
for (int i = 0; i < capacity; i++) { for (int i = 0; i < capacity; i++) {
DisallowHeapAllocation no_gc;
Object* key = dict->KeyAt(i); Object* key = dict->KeyAt(i);
if (key->IsNumber()) { if (key->IsNumber()) {
uint32_t number = static_cast<uint32_t>(key->Number()); uint32_t number = static_cast<uint32_t>(key->Number());
...@@ -1443,8 +1445,7 @@ class DictionaryElementsAccessor ...@@ -1443,8 +1445,7 @@ class DictionaryElementsAccessor
} }
} }
if (new_length != length) { if (new_length != length) {
MaybeObject* maybe_object = heap->NumberFromUint32(new_length); length_object = isolate->factory()->NewNumberFromUint(new_length);
if (!maybe_object->To(&length_object)) return maybe_object;
} }
} }
...@@ -1452,13 +1453,12 @@ class DictionaryElementsAccessor ...@@ -1452,13 +1453,12 @@ class DictionaryElementsAccessor
// If the length of a slow array is reset to zero, we clear // If the length of a slow array is reset to zero, we clear
// the array and flush backing storage. This has the added // the array and flush backing storage. This has the added
// benefit that the array returns to fast mode. // benefit that the array returns to fast mode.
Object* obj; JSObject::ResetElements(array);
MaybeObject* maybe_obj = array->ResetElements();
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
} else { } else {
DisallowHeapAllocation no_gc;
// Remove elements that should be deleted. // Remove elements that should be deleted.
int removed_entries = 0; int removed_entries = 0;
Object* the_hole_value = heap->the_hole_value(); Object* the_hole_value = isolate->heap()->the_hole_value();
for (int i = 0; i < capacity; i++) { for (int i = 0; i < capacity; i++) {
Object* key = dict->KeyAt(i); Object* key = dict->KeyAt(i);
if (key->IsNumber()) { if (key->IsNumber()) {
...@@ -1476,18 +1476,6 @@ class DictionaryElementsAccessor ...@@ -1476,18 +1476,6 @@ class DictionaryElementsAccessor
return length_object; return length_object;
} }
// TODO(ishell): Temporary wrapper until handlified.
MUST_USE_RESULT static Handle<Object> SetLengthWithoutNormalize(
Handle<FixedArrayBase> store,
Handle<JSArray> array,
Handle<Object> length_object,
uint32_t length) {
CALL_HEAP_FUNCTION(array->GetIsolate(),
SetLengthWithoutNormalize(
*store, *array, *length_object, length),
Object);
}
MUST_USE_RESULT static MaybeObject* DeleteCommon( MUST_USE_RESULT static MaybeObject* DeleteCommon(
JSObject* obj, JSObject* obj,
uint32_t key, uint32_t key,
......
...@@ -143,6 +143,23 @@ Handle<DescriptorArray> Factory::NewDescriptorArray(int number_of_descriptors, ...@@ -143,6 +143,23 @@ Handle<DescriptorArray> Factory::NewDescriptorArray(int number_of_descriptors,
} }
Handle<TransitionArray> Factory::NewTransitionArray(int number_of_transitions) {
ASSERT(0 <= number_of_transitions);
CALL_HEAP_FUNCTION(isolate(),
TransitionArray::Allocate(
isolate(), number_of_transitions),
TransitionArray);
}
Handle<TransitionArray> Factory::NewSimpleTransitionArray(Handle<Map> target) {
CALL_HEAP_FUNCTION(isolate(),
TransitionArray::AllocateSimple(
isolate(), *target),
TransitionArray);
}
Handle<DeoptimizationInputData> Factory::NewDeoptimizationInputData( Handle<DeoptimizationInputData> Factory::NewDeoptimizationInputData(
int deopt_entry_count, int deopt_entry_count,
PretenureFlag pretenure) { PretenureFlag pretenure) {
......
...@@ -57,6 +57,8 @@ class Factory V8_FINAL { ...@@ -57,6 +57,8 @@ class Factory V8_FINAL {
Handle<DescriptorArray> NewDescriptorArray(int number_of_descriptors, Handle<DescriptorArray> NewDescriptorArray(int number_of_descriptors,
int slack = 0); int slack = 0);
Handle<TransitionArray> NewTransitionArray(int number_of_transitions);
Handle<TransitionArray> NewSimpleTransitionArray(Handle<Map> target);
Handle<DeoptimizationInputData> NewDeoptimizationInputData( Handle<DeoptimizationInputData> NewDeoptimizationInputData(
int deopt_entry_count, int deopt_entry_count,
PretenureFlag pretenure); PretenureFlag pretenure);
......
...@@ -1750,28 +1750,6 @@ void JSObject::EnsureCanContainElements(Handle<JSObject> object, ...@@ -1750,28 +1750,6 @@ void JSObject::EnsureCanContainElements(Handle<JSObject> object,
} }
MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate,
ElementsKind to_kind) {
Map* current_map = map();
ElementsKind from_kind = current_map->elements_kind();
if (from_kind == to_kind) return current_map;
Context* native_context = isolate->context()->native_context();
Object* maybe_array_maps = native_context->js_array_maps();
if (maybe_array_maps->IsFixedArray()) {
FixedArray* array_maps = FixedArray::cast(maybe_array_maps);
if (array_maps->get(from_kind) == current_map) {
Object* maybe_transitioned_map = array_maps->get(to_kind);
if (maybe_transitioned_map->IsMap()) {
return Map::cast(maybe_transitioned_map);
}
}
}
return GetElementsTransitionMapSlow(to_kind);
}
void JSObject::SetMapAndElements(Handle<JSObject> object, void JSObject::SetMapAndElements(Handle<JSObject> object,
Handle<Map> new_map, Handle<Map> new_map,
Handle<FixedArrayBase> value) { Handle<FixedArrayBase> value) {
...@@ -1800,50 +1778,8 @@ void JSObject::initialize_properties() { ...@@ -1800,50 +1778,8 @@ void JSObject::initialize_properties() {
void JSObject::initialize_elements() { void JSObject::initialize_elements() {
if (map()->has_fast_smi_or_object_elements() || FixedArrayBase* elements = map()->GetInitialElements();
map()->has_fast_double_elements()) { WRITE_FIELD(this, kElementsOffset, elements);
ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
} else if (map()->has_external_array_elements()) {
ExternalArray* empty_array = GetHeap()->EmptyExternalArrayForMap(map());
ASSERT(!GetHeap()->InNewSpace(empty_array));
WRITE_FIELD(this, kElementsOffset, empty_array);
} else if (map()->has_fixed_typed_array_elements()) {
FixedTypedArrayBase* empty_array =
GetHeap()->EmptyFixedTypedArrayForMap(map());
ASSERT(!GetHeap()->InNewSpace(empty_array));
WRITE_FIELD(this, kElementsOffset, empty_array);
} else {
UNREACHABLE();
}
}
MaybeObject* JSObject::ResetElements() {
if (map()->is_observed()) {
// Maintain invariant that observed elements are always in dictionary mode.
SeededNumberDictionary* dictionary;
MaybeObject* maybe = SeededNumberDictionary::Allocate(GetHeap(), 0);
if (!maybe->To(&dictionary)) return maybe;
if (map() == GetHeap()->sloppy_arguments_elements_map()) {
FixedArray::cast(elements())->set(1, dictionary);
} else {
set_elements(dictionary);
}
return this;
}
ElementsKind elements_kind = GetInitialFastElementsKind();
if (!FLAG_smi_only_arrays) {
elements_kind = FastSmiToObjectElementsKind(elements_kind);
}
MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(), elements_kind);
Map* map;
if (!maybe->To(&map)) return maybe;
set_map(map);
initialize_elements();
return this;
} }
...@@ -2692,6 +2628,27 @@ void Map::LookupTransition(JSObject* holder, ...@@ -2692,6 +2628,27 @@ void Map::LookupTransition(JSObject* holder,
} }
FixedArrayBase* Map::GetInitialElements() {
if (has_fast_smi_or_object_elements() ||
has_fast_double_elements()) {
ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
return GetHeap()->empty_fixed_array();
} else if (has_external_array_elements()) {
ExternalArray* empty_array = GetHeap()->EmptyExternalArrayForMap(this);
ASSERT(!GetHeap()->InNewSpace(empty_array));
return empty_array;
} else if (has_fixed_typed_array_elements()) {
FixedTypedArrayBase* empty_array =
GetHeap()->EmptyFixedTypedArrayForMap(this);
ASSERT(!GetHeap()->InNewSpace(empty_array));
return empty_array;
} else {
UNREACHABLE();
}
return NULL;
}
Object** DescriptorArray::GetKeySlot(int descriptor_number) { Object** DescriptorArray::GetKeySlot(int descriptor_number) {
ASSERT(descriptor_number < number_of_descriptors()); ASSERT(descriptor_number < number_of_descriptors());
return RawFieldOfElementAt(ToKeyIndex(descriptor_number)); return RawFieldOfElementAt(ToKeyIndex(descriptor_number));
...@@ -2796,8 +2753,8 @@ AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) { ...@@ -2796,8 +2753,8 @@ AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
void DescriptorArray::Get(int descriptor_number, Descriptor* desc) { void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
desc->Init(GetKey(descriptor_number), desc->Init(handle(GetKey(descriptor_number), GetIsolate()),
GetValue(descriptor_number), handle(GetValue(descriptor_number), GetIsolate()),
GetDetails(descriptor_number)); GetDetails(descriptor_number));
} }
...@@ -2810,10 +2767,10 @@ void DescriptorArray::Set(int descriptor_number, ...@@ -2810,10 +2767,10 @@ void DescriptorArray::Set(int descriptor_number,
NoIncrementalWriteBarrierSet(this, NoIncrementalWriteBarrierSet(this,
ToKeyIndex(descriptor_number), ToKeyIndex(descriptor_number),
desc->GetKey()); *desc->GetKey());
NoIncrementalWriteBarrierSet(this, NoIncrementalWriteBarrierSet(this,
ToValueIndex(descriptor_number), ToValueIndex(descriptor_number),
desc->GetValue()); *desc->GetValue());
NoIncrementalWriteBarrierSet(this, NoIncrementalWriteBarrierSet(this,
ToDetailsIndex(descriptor_number), ToDetailsIndex(descriptor_number),
desc->GetDetails().AsSmi()); desc->GetDetails().AsSmi());
...@@ -2824,14 +2781,15 @@ void DescriptorArray::Set(int descriptor_number, Descriptor* desc) { ...@@ -2824,14 +2781,15 @@ void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
// Range check. // Range check.
ASSERT(descriptor_number < number_of_descriptors()); ASSERT(descriptor_number < number_of_descriptors());
set(ToKeyIndex(descriptor_number), desc->GetKey()); set(ToKeyIndex(descriptor_number), *desc->GetKey());
set(ToValueIndex(descriptor_number), desc->GetValue()); set(ToValueIndex(descriptor_number), *desc->GetValue());
set(ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi()); set(ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi());
} }
void DescriptorArray::Append(Descriptor* desc, void DescriptorArray::Append(Descriptor* desc,
const WhitenessWitness& witness) { const WhitenessWitness& witness) {
DisallowHeapAllocation no_gc;
int descriptor_number = number_of_descriptors(); int descriptor_number = number_of_descriptors();
SetNumberOfDescriptors(descriptor_number + 1); SetNumberOfDescriptors(descriptor_number + 1);
Set(descriptor_number, desc, witness); Set(descriptor_number, desc, witness);
...@@ -2851,6 +2809,7 @@ void DescriptorArray::Append(Descriptor* desc, ...@@ -2851,6 +2809,7 @@ void DescriptorArray::Append(Descriptor* desc,
void DescriptorArray::Append(Descriptor* desc) { void DescriptorArray::Append(Descriptor* desc) {
DisallowHeapAllocation no_gc;
int descriptor_number = number_of_descriptors(); int descriptor_number = number_of_descriptors();
SetNumberOfDescriptors(descriptor_number + 1); SetNumberOfDescriptors(descriptor_number + 1);
Set(descriptor_number, desc); Set(descriptor_number, desc);
...@@ -5066,14 +5025,6 @@ bool Map::CanHaveMoreTransitions() { ...@@ -5066,14 +5025,6 @@ bool Map::CanHaveMoreTransitions() {
} }
MaybeObject* Map::AddTransition(Name* key,
Map* target,
SimpleTransitionFlag flag) {
if (HasTransitionArray()) return transitions()->CopyInsert(key, target);
return TransitionArray::NewWith(flag, key, target, GetBackPointer());
}
void Map::SetTransition(int transition_index, Map* target) { void Map::SetTransition(int transition_index, Map* target) {
transitions()->SetTarget(transition_index, target); transitions()->SetTarget(transition_index, target);
} }
...@@ -5090,18 +5041,6 @@ int Map::SearchTransition(Name* name) { ...@@ -5090,18 +5041,6 @@ int Map::SearchTransition(Name* name) {
} }
MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) {
TransitionArray* transitions;
MaybeObject* maybe_transitions = AddTransition(
GetHeap()->elements_transition_symbol(),
transitioned_map,
FULL_TRANSITION);
if (!maybe_transitions->To(&transitions)) return maybe_transitions;
set_transitions(transitions);
return transitions;
}
FixedArray* Map::GetPrototypeTransitions() { FixedArray* Map::GetPrototypeTransitions() {
if (!HasTransitionArray()) return GetHeap()->empty_fixed_array(); if (!HasTransitionArray()) return GetHeap()->empty_fixed_array();
if (!transitions()->HasPrototypeTransitions()) { if (!transitions()->HasPrototypeTransitions()) {
......
This diff is collapsed.
...@@ -2186,7 +2186,6 @@ class JSObject: public JSReceiver { ...@@ -2186,7 +2186,6 @@ class JSObject: public JSReceiver {
// arguments object. // arguments object.
DECL_ACCESSORS(elements, FixedArrayBase) DECL_ACCESSORS(elements, FixedArrayBase)
inline void initialize_elements(); inline void initialize_elements();
MUST_USE_RESULT inline MaybeObject* ResetElements();
static void ResetElements(Handle<JSObject> object); static void ResetElements(Handle<JSObject> object);
static inline void SetMapAndElements(Handle<JSObject> object, static inline void SetMapAndElements(Handle<JSObject> object,
Handle<Map> map, Handle<Map> map,
...@@ -2580,11 +2579,8 @@ class JSObject: public JSReceiver { ...@@ -2580,11 +2579,8 @@ class JSObject: public JSReceiver {
// map and the ElementsKind set. // map and the ElementsKind set.
static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object, static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
ElementsKind to_kind); ElementsKind to_kind);
inline MUST_USE_RESULT MaybeObject* GetElementsTransitionMap( static Handle<Map> GetElementsTransitionMapSlow(Handle<JSObject> object,
Isolate* isolate, ElementsKind elements_kind);
ElementsKind elements_kind);
MUST_USE_RESULT MaybeObject* GetElementsTransitionMapSlow(
ElementsKind elements_kind);
static void TransitionElementsKind(Handle<JSObject> object, static void TransitionElementsKind(Handle<JSObject> object,
ElementsKind to_kind); ElementsKind to_kind);
...@@ -3481,17 +3477,13 @@ class DescriptorArray: public FixedArray { ...@@ -3481,17 +3477,13 @@ class DescriptorArray: public FixedArray {
int new_size, int new_size,
DescriptorArray* other); DescriptorArray* other);
MUST_USE_RESULT MaybeObject* CopyUpTo(int enumeration_index) { static Handle<DescriptorArray> CopyUpTo(Handle<DescriptorArray> desc,
return CopyUpToAddAttributes(enumeration_index, NONE); int enumeration_index);
}
static Handle<DescriptorArray> CopyUpToAddAttributes( static Handle<DescriptorArray> CopyUpToAddAttributes(
Handle<DescriptorArray> desc, Handle<DescriptorArray> desc,
int enumeration_index, int enumeration_index,
PropertyAttributes attributes); PropertyAttributes attributes);
MUST_USE_RESULT MaybeObject* CopyUpToAddAttributes(
int enumeration_index,
PropertyAttributes attributes);
// Sort the instance descriptors by the hash codes of their keys. // Sort the instance descriptors by the hash codes of their keys.
void Sort(); void Sort();
...@@ -6172,20 +6164,17 @@ class Map: public HeapObject { ...@@ -6172,20 +6164,17 @@ class Map: public HeapObject {
inline bool HasTransitionArray(); inline bool HasTransitionArray();
inline bool HasElementsTransition(); inline bool HasElementsTransition();
inline Map* elements_transition_map(); inline Map* elements_transition_map();
MUST_USE_RESULT inline MaybeObject* set_elements_transition_map( static Handle<TransitionArray> SetElementsTransitionMap(
Map* transitioned_map); Handle<Map> map, Handle<Map> transitioned_map);
inline void SetTransition(int transition_index, Map* target); inline void SetTransition(int transition_index, Map* target);
inline Map* GetTransition(int transition_index); inline Map* GetTransition(int transition_index);
inline int SearchTransition(Name* name); inline int SearchTransition(Name* name);
inline FixedArrayBase* GetInitialElements();
static Handle<TransitionArray> AddTransition(Handle<Map> map, static Handle<TransitionArray> AddTransition(Handle<Map> map,
Handle<Name> key, Handle<Name> key,
Handle<Map> target, Handle<Map> target,
SimpleTransitionFlag flag); SimpleTransitionFlag flag);
MUST_USE_RESULT inline MaybeObject* AddTransition(Name* key,
Map* target,
SimpleTransitionFlag flag);
DECL_ACCESSORS(transitions, TransitionArray) DECL_ACCESSORS(transitions, TransitionArray)
inline void ClearTransitions(Heap* heap, inline void ClearTransitions(Heap* heap,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER); WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
...@@ -6391,37 +6380,42 @@ class Map: public HeapObject { ...@@ -6391,37 +6380,42 @@ class Map: public HeapObject {
MUST_USE_RESULT MaybeObject* RawCopy(int instance_size); MUST_USE_RESULT MaybeObject* RawCopy(int instance_size);
static Handle<Map> CopyDropDescriptors(Handle<Map> map); static Handle<Map> CopyDropDescriptors(Handle<Map> map);
MUST_USE_RESULT MaybeObject* CopyDropDescriptors(); MUST_USE_RESULT MaybeObject* CopyDropDescriptors();
static Handle<Map> CopyReplaceDescriptors(Handle<Map> map, static Handle<Map> CopyReplaceDescriptors(
Handle<DescriptorArray> descriptors, Handle<Map> map,
TransitionFlag flag, Handle<DescriptorArray> descriptors,
Handle<Name> name); TransitionFlag flag,
MUST_USE_RESULT MaybeObject* CopyReplaceDescriptors( Handle<Name> name,
DescriptorArray* descriptors, SimpleTransitionFlag simple_flag = FULL_TRANSITION);
static Handle<Map> CopyReplaceDescriptors(
Handle<Map> map,
Handle<DescriptorArray> descriptors,
TransitionFlag flag, TransitionFlag flag,
Name* name = NULL,
SimpleTransitionFlag simple_flag = FULL_TRANSITION); SimpleTransitionFlag simple_flag = FULL_TRANSITION);
static Handle<Map> CopyInstallDescriptors( static Handle<Map> CopyInstallDescriptors(
Handle<Map> map, Handle<Map> map,
int new_descriptor, int new_descriptor,
Handle<DescriptorArray> descriptors); Handle<DescriptorArray> descriptors);
MUST_USE_RESULT MaybeObject* ShareDescriptor(DescriptorArray* descriptors, static Handle<Map> ShareDescriptor(Handle<Map> map,
Descriptor* descriptor); Handle<DescriptorArray> descriptors,
MUST_USE_RESULT MaybeObject* CopyAddDescriptor(Descriptor* descriptor, Descriptor* descriptor);
TransitionFlag flag); static Handle<Map> CopyAddDescriptor(Handle<Map> map,
MUST_USE_RESULT MaybeObject* CopyInsertDescriptor(Descriptor* descriptor, Descriptor* descriptor,
TransitionFlag flag); TransitionFlag flag);
MUST_USE_RESULT MaybeObject* CopyReplaceDescriptor( static Handle<Map> CopyInsertDescriptor(Handle<Map> map,
DescriptorArray* descriptors, Descriptor* descriptor,
TransitionFlag flag);
static Handle<Map> CopyReplaceDescriptor(
Handle<Map> map,
Handle<DescriptorArray> descriptors,
Descriptor* descriptor, Descriptor* descriptor,
int index, int index,
TransitionFlag flag); TransitionFlag flag);
MUST_USE_RESULT MaybeObject* AsElementsKind(ElementsKind kind);
static Handle<Map> AsElementsKind(Handle<Map> map, ElementsKind kind); static Handle<Map> AsElementsKind(Handle<Map> map, ElementsKind kind);
MUST_USE_RESULT MaybeObject* CopyAsElementsKind(ElementsKind kind, static Handle<Map> CopyAsElementsKind(Handle<Map> map,
TransitionFlag flag); ElementsKind kind,
TransitionFlag flag);
static Handle<Map> CopyForObserved(Handle<Map> map); static Handle<Map> CopyForObserved(Handle<Map> map);
...@@ -6437,7 +6431,6 @@ class Map: public HeapObject { ...@@ -6437,7 +6431,6 @@ class Map: public HeapObject {
static Handle<Map> Copy(Handle<Map> map); static Handle<Map> Copy(Handle<Map> map);
static Handle<Map> Create(Handle<JSFunction> constructor, static Handle<Map> Create(Handle<JSFunction> constructor,
int extra_inobject_properties); int extra_inobject_properties);
MUST_USE_RESULT MaybeObject* Copy();
// Returns the next free property index (only valid for FAST MODE). // Returns the next free property index (only valid for FAST MODE).
int NextFreePropertyIndex(); int NextFreePropertyIndex();
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define V8_PROPERTY_H_ #define V8_PROPERTY_H_
#include "isolate.h" #include "isolate.h"
#include "factory.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -17,17 +18,15 @@ namespace internal { ...@@ -17,17 +18,15 @@ namespace internal {
// optionally a piece of data. // optionally a piece of data.
class Descriptor BASE_EMBEDDED { class Descriptor BASE_EMBEDDED {
public: public:
MUST_USE_RESULT MaybeObject* KeyToUniqueName() { void KeyToUniqueName() {
if (!key_->IsUniqueName()) { if (!key_->IsUniqueName()) {
MaybeObject* maybe_result = key_ = key_->GetIsolate()->factory()->InternalizeString(
key_->GetIsolate()->heap()->InternalizeString(String::cast(key_)); Handle<String>::cast(key_));
if (!maybe_result->To(&key_)) return maybe_result;
} }
return key_;
} }
Name* GetKey() { return key_; } Handle<Name> GetKey() { return key_; }
Object* GetValue() { return value_; } Handle<Object> GetValue() { return value_; }
PropertyDetails GetDetails() { return details_; } PropertyDetails GetDetails() { return details_; }
#ifdef OBJECT_PRINT #ifdef OBJECT_PRINT
...@@ -37,26 +36,26 @@ class Descriptor BASE_EMBEDDED { ...@@ -37,26 +36,26 @@ class Descriptor BASE_EMBEDDED {
void SetSortedKeyIndex(int index) { details_ = details_.set_pointer(index); } void SetSortedKeyIndex(int index) { details_ = details_.set_pointer(index); }
private: private:
Name* key_; Handle<Name> key_;
Object* value_; Handle<Object> value_;
PropertyDetails details_; PropertyDetails details_;
protected: protected:
Descriptor() : details_(Smi::FromInt(0)) {} 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; key_ = key;
value_ = value; value_ = value;
details_ = details; details_ = details;
} }
Descriptor(Name* key, Object* value, PropertyDetails details) Descriptor(Handle<Name> key, Handle<Object> value, PropertyDetails details)
: key_(key), : key_(key),
value_(value), value_(value),
details_(details) { } details_(details) { }
Descriptor(Name* key, Descriptor(Handle<Name> key,
Object* value, Handle<Object> value,
PropertyAttributes attributes, PropertyAttributes attributes,
PropertyType type, PropertyType type,
Representation representation, Representation representation,
...@@ -71,19 +70,19 @@ class Descriptor BASE_EMBEDDED { ...@@ -71,19 +70,19 @@ class Descriptor BASE_EMBEDDED {
class FieldDescriptor V8_FINAL : public Descriptor { class FieldDescriptor V8_FINAL : public Descriptor {
public: public:
FieldDescriptor(Name* key, FieldDescriptor(Handle<Name> key,
int field_index, int field_index,
PropertyAttributes attributes, PropertyAttributes attributes,
Representation representation) Representation representation)
: Descriptor(key, Smi::FromInt(0), attributes, : Descriptor(key, handle(Smi::FromInt(0), key->GetIsolate()), attributes,
FIELD, representation, field_index) {} FIELD, representation, field_index) {}
}; };
class ConstantDescriptor V8_FINAL : public Descriptor { class ConstantDescriptor V8_FINAL : public Descriptor {
public: public:
ConstantDescriptor(Name* key, ConstantDescriptor(Handle<Name> key,
Object* value, Handle<Object> value,
PropertyAttributes attributes) PropertyAttributes attributes)
: Descriptor(key, value, attributes, CONSTANT, : Descriptor(key, value, attributes, CONSTANT,
value->OptimalRepresentation()) {} value->OptimalRepresentation()) {}
...@@ -92,8 +91,8 @@ class ConstantDescriptor V8_FINAL : public Descriptor { ...@@ -92,8 +91,8 @@ class ConstantDescriptor V8_FINAL : public Descriptor {
class CallbacksDescriptor V8_FINAL : public Descriptor { class CallbacksDescriptor V8_FINAL : public Descriptor {
public: public:
CallbacksDescriptor(Name* key, CallbacksDescriptor(Handle<Name> key,
Object* foreign, Handle<Object> foreign,
PropertyAttributes attributes) PropertyAttributes attributes)
: Descriptor(key, foreign, attributes, CALLBACKS, : Descriptor(key, foreign, attributes, CALLBACKS,
Representation::Tagged()) {} Representation::Tagged()) {}
......
...@@ -2944,32 +2944,32 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) { ...@@ -2944,32 +2944,32 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) {
RUNTIME_ASSERT(args.length() == 1); RUNTIME_ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
String* name = isolate->heap()->prototype_string(); Handle<String> name = isolate->factory()->prototype_string();
if (function->HasFastProperties()) { if (function->HasFastProperties()) {
// Construct a new field descriptor with updated attributes. // Construct a new field descriptor with updated attributes.
DescriptorArray* instance_desc = function->map()->instance_descriptors(); Handle<DescriptorArray> instance_desc =
handle(function->map()->instance_descriptors());
int index = instance_desc->SearchWithCache(name, function->map()); int index = instance_desc->SearchWithCache(*name, function->map());
ASSERT(index != DescriptorArray::kNotFound); ASSERT(index != DescriptorArray::kNotFound);
PropertyDetails details = instance_desc->GetDetails(index); PropertyDetails details = instance_desc->GetDetails(index);
CallbacksDescriptor new_desc(name, CallbacksDescriptor new_desc(
instance_desc->GetValue(index), name,
handle(instance_desc->GetValue(index), isolate),
static_cast<PropertyAttributes>(details.attributes() | READ_ONLY)); static_cast<PropertyAttributes>(details.attributes() | READ_ONLY));
// Create a new map featuring the new field descriptors array. // Create a new map featuring the new field descriptors array.
Map* new_map; Handle<Map> map = handle(function->map());
MaybeObject* maybe_map = Handle<Map> new_map = Map::CopyReplaceDescriptor(
function->map()->CopyReplaceDescriptor( map, instance_desc, &new_desc, index, OMIT_TRANSITION);
instance_desc, &new_desc, index, OMIT_TRANSITION);
if (!maybe_map->To(&new_map)) return maybe_map;
JSObject::MigrateToMap(function, handle(new_map)); JSObject::MigrateToMap(function, new_map);
} else { // Dictionary properties. } else { // Dictionary properties.
// Directly manipulate the property details. // Directly manipulate the property details.
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
int entry = function->property_dictionary()->FindEntry(name); int entry = function->property_dictionary()->FindEntry(*name);
ASSERT(entry != NameDictionary::kNotFound); ASSERT(entry != NameDictionary::kNotFound);
PropertyDetails details = function->property_dictionary()->DetailsAt(entry); PropertyDetails details = function->property_dictionary()->DetailsAt(entry);
PropertyDetails new_details( PropertyDetails new_details(
......
...@@ -55,6 +55,17 @@ MaybeObject* TransitionArray::Allocate(Isolate* isolate, ...@@ -55,6 +55,17 @@ MaybeObject* TransitionArray::Allocate(Isolate* isolate,
} }
MaybeObject* TransitionArray::AllocateSimple(Isolate* isolate,
Map* target) {
FixedArray* array;
MaybeObject* maybe_array =
AllocateRaw(isolate, kSimpleTransitionSize);
if (!maybe_array->To(&array)) return maybe_array;
array->set(kSimpleTransitionTarget, target);
return array;
}
void TransitionArray::NoIncrementalWriteBarrierCopyFrom(TransitionArray* origin, void TransitionArray::NoIncrementalWriteBarrierCopyFrom(TransitionArray* origin,
int origin_transition, int origin_transition,
int target_transition) { int target_transition) {
...@@ -69,23 +80,20 @@ static bool InsertionPointFound(Name* key1, Name* key2) { ...@@ -69,23 +80,20 @@ static bool InsertionPointFound(Name* key1, Name* key2) {
} }
MaybeObject* TransitionArray::NewWith(SimpleTransitionFlag flag, Handle<TransitionArray> TransitionArray::NewWith(SimpleTransitionFlag flag,
Name* key, Handle<Name> key,
Map* target, Handle<Map> target,
Object* back_pointer) { Handle<Object> back_pointer) {
TransitionArray* result; Handle<TransitionArray> result;
MaybeObject* maybe_result; Factory* factory = key->GetIsolate()->factory();
if (flag == SIMPLE_TRANSITION) { if (flag == SIMPLE_TRANSITION) {
maybe_result = AllocateRaw(target->GetIsolate(), kSimpleTransitionSize); result = factory->NewSimpleTransitionArray(target);
if (!maybe_result->To(&result)) return maybe_result;
result->set(kSimpleTransitionTarget, target);
} else { } else {
maybe_result = Allocate(target->GetIsolate(), 1); result = factory->NewTransitionArray(1);
if (!maybe_result->To(&result)) return maybe_result; result->NoIncrementalWriteBarrierSet(0, *key, *target);
result->NoIncrementalWriteBarrierSet(0, key, target);
} }
result->set_back_pointer_storage(back_pointer); result->set_back_pointer_storage(*back_pointer);
return result; return result;
} }
...@@ -106,49 +114,67 @@ MaybeObject* TransitionArray::ExtendToFullTransitionArray() { ...@@ -106,49 +114,67 @@ MaybeObject* TransitionArray::ExtendToFullTransitionArray() {
} }
MaybeObject* TransitionArray::CopyInsert(Name* name, Map* target) { Handle<TransitionArray> TransitionArray::CopyInsert(Handle<Map> map,
TransitionArray* result; Handle<Name> name,
Handle<Map> target) {
ASSERT(map->HasTransitionArray());
Handle<TransitionArray> result;
int number_of_transitions = this->number_of_transitions(); int number_of_transitions = map->transitions()->number_of_transitions();
int new_size = number_of_transitions; int new_size = number_of_transitions;
int insertion_index = this->Search(name); int insertion_index = map->transitions()->Search(*name);
if (insertion_index == kNotFound) ++new_size; if (insertion_index == kNotFound) ++new_size;
MaybeObject* maybe_array; result = map->GetIsolate()->factory()->NewTransitionArray(new_size);
maybe_array = TransitionArray::Allocate(GetIsolate(), new_size);
if (!maybe_array->To(&result)) return maybe_array; // The map's transition array may have grown smaller during the allocation
// above as it was weakly traversed. Trim the result copy if needed, and
// recompute variables.
DisallowHeapAllocation no_gc;
TransitionArray* array = map->transitions();
if (array->number_of_transitions() != number_of_transitions) {
ASSERT(array->number_of_transitions() < number_of_transitions);
number_of_transitions = array->number_of_transitions();
new_size = number_of_transitions;
insertion_index = array->Search(*name);
if (insertion_index == kNotFound) ++new_size;
if (HasPrototypeTransitions()) { result->Shrink(new_size);
result->SetPrototypeTransitions(GetPrototypeTransitions()); }
if (array->HasPrototypeTransitions()) {
result->SetPrototypeTransitions(array->GetPrototypeTransitions());
} }
if (insertion_index != kNotFound) { if (insertion_index != kNotFound) {
for (int i = 0; i < number_of_transitions; ++i) { for (int i = 0; i < number_of_transitions; ++i) {
if (i != insertion_index) { if (i != insertion_index) {
result->NoIncrementalWriteBarrierCopyFrom(this, i, i); result->NoIncrementalWriteBarrierCopyFrom(array, i, i);
} }
} }
result->NoIncrementalWriteBarrierSet(insertion_index, name, target); result->NoIncrementalWriteBarrierSet(insertion_index, *name, *target);
result->set_back_pointer_storage(back_pointer_storage()); result->set_back_pointer_storage(array->back_pointer_storage());
return result; return result;
} }
insertion_index = 0; insertion_index = 0;
for (; insertion_index < number_of_transitions; ++insertion_index) { for (; insertion_index < number_of_transitions; ++insertion_index) {
if (InsertionPointFound(GetKey(insertion_index), name)) break; if (InsertionPointFound(array->GetKey(insertion_index), *name)) break;
result->NoIncrementalWriteBarrierCopyFrom( result->NoIncrementalWriteBarrierCopyFrom(
this, insertion_index, insertion_index); array, insertion_index, insertion_index);
} }
result->NoIncrementalWriteBarrierSet(insertion_index, name, target); result->NoIncrementalWriteBarrierSet(insertion_index, *name, *target);
for (; insertion_index < number_of_transitions; ++insertion_index) { for (; insertion_index < number_of_transitions; ++insertion_index) {
result->NoIncrementalWriteBarrierCopyFrom( result->NoIncrementalWriteBarrierCopyFrom(
this, insertion_index, insertion_index + 1); array, insertion_index, insertion_index + 1);
} }
result->set_back_pointer_storage(back_pointer_storage()); result->set_back_pointer_storage(array->back_pointer_storage());
return result; return result;
} }
......
...@@ -96,18 +96,19 @@ class TransitionArray: public FixedArray { ...@@ -96,18 +96,19 @@ class TransitionArray: public FixedArray {
inline int number_of_entries() { return number_of_transitions(); } inline int number_of_entries() { return number_of_transitions(); }
// Allocate a new transition array with a single entry. // Allocate a new transition array with a single entry.
static MUST_USE_RESULT MaybeObject* NewWith( static Handle<TransitionArray> NewWith(SimpleTransitionFlag flag,
SimpleTransitionFlag flag, Handle<Name> key,
Name* key, Handle<Map> target,
Map* target, Handle<Object> back_pointer);
Object* back_pointer);
MUST_USE_RESULT MaybeObject* ExtendToFullTransitionArray(); MUST_USE_RESULT MaybeObject* ExtendToFullTransitionArray();
// Copy the transition array, inserting a new transition. // Copy the transition array, inserting a new transition.
// TODO(verwaest): This should not cause an existing transition to be // TODO(verwaest): This should not cause an existing transition to be
// overwritten. // overwritten.
MUST_USE_RESULT MaybeObject* CopyInsert(Name* name, Map* target); static Handle<TransitionArray> CopyInsert(Handle<Map> map,
Handle<Name> name,
Handle<Map> target);
// Copy a single transition from the origin array. // Copy a single transition from the origin array.
inline void NoIncrementalWriteBarrierCopyFrom(TransitionArray* origin, inline void NoIncrementalWriteBarrierCopyFrom(TransitionArray* origin,
...@@ -121,6 +122,9 @@ class TransitionArray: public FixedArray { ...@@ -121,6 +122,9 @@ class TransitionArray: public FixedArray {
MUST_USE_RESULT static MaybeObject* Allocate( MUST_USE_RESULT static MaybeObject* Allocate(
Isolate* isolate, int number_of_transitions); Isolate* isolate, int number_of_transitions);
MUST_USE_RESULT static MaybeObject* AllocateSimple(
Isolate* isolate, Map* target);
bool IsSimpleTransition() { bool IsSimpleTransition() {
return length() == kSimpleTransitionSize && return length() == kSimpleTransitionSize &&
get(kSimpleTransitionTarget)->IsHeapObject() && get(kSimpleTransitionTarget)->IsHeapObject() &&
......
...@@ -142,8 +142,8 @@ TEST(StressJS) { ...@@ -142,8 +142,8 @@ TEST(StressJS) {
v8::internal::DescriptorArray::WhitenessWitness witness(*new_descriptors); v8::internal::DescriptorArray::WhitenessWitness witness(*new_descriptors);
map->set_instance_descriptors(*new_descriptors); map->set_instance_descriptors(*new_descriptors);
CallbacksDescriptor d(*name, CallbacksDescriptor d(name,
*foreign, foreign,
static_cast<PropertyAttributes>(0)); static_cast<PropertyAttributes>(0));
map->AppendDescriptor(&d, witness); map->AppendDescriptor(&d, witness);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment