Author: [email protected]
Date: Fri Jul 10 12:25:18 2009
New Revision: 2428
Modified:
branches/bleeding_edge/src/bootstrapper.cc
branches/bleeding_edge/src/factory.cc
branches/bleeding_edge/src/handles.cc
branches/bleeding_edge/src/objects-debug.cc
branches/bleeding_edge/src/objects-inl.h
branches/bleeding_edge/src/objects.cc
branches/bleeding_edge/src/objects.h
branches/bleeding_edge/src/property.cc
branches/bleeding_edge/src/property.h
branches/bleeding_edge/src/spaces.cc
branches/bleeding_edge/src/string-stream.cc
Log:
Remove the descriptor stream abstractions.
The abstractions have led to bugs because it looks like descriptor
streams are GC safe but they are not.
I have moved the descriptor stream helper functions to descriptor
arrays and I find most of the code just as readable now as it was
before.
Review URL: http://codereview.chromium.org/149458
Modified: branches/bleeding_edge/src/bootstrapper.cc
==============================================================================
--- branches/bleeding_edge/src/bootstrapper.cc (original)
+++ branches/bleeding_edge/src/bootstrapper.cc Fri Jul 10 12:25:18 2009
@@ -1373,43 +1373,35 @@
if (from->HasFastProperties()) {
Handle<DescriptorArray> descs =
Handle<DescriptorArray>(from->map()->instance_descriptors());
- int offset = 0;
- while (true) {
- // Iterating through the descriptors is not gc safe so we have to
- // store the value in a handle and create a new stream for each
entry.
- DescriptorReader stream(*descs, offset);
- if (stream.eos()) break;
- // We have to read out the next offset before we do anything that may
- // cause a gc, since the DescriptorReader is not gc safe.
- offset = stream.next_position();
- PropertyDetails details = stream.GetDetails();
+ for (int i = 0; i < descs->number_of_descriptors(); i++) {
+ PropertyDetails details = PropertyDetails(descs->GetDetails(i));
switch (details.type()) {
case FIELD: {
HandleScope inner;
- Handle<String> key = Handle<String>(stream.GetKey());
- int index = stream.GetFieldIndex();
+ Handle<String> key = Handle<String>(descs->GetKey(i));
+ int index = descs->GetFieldIndex(i);
Handle<Object> value =
Handle<Object>(from->FastPropertyAt(index));
SetProperty(to, key, value, details.attributes());
break;
}
case CONSTANT_FUNCTION: {
HandleScope inner;
- Handle<String> key = Handle<String>(stream.GetKey());
+ Handle<String> key = Handle<String>(descs->GetKey(i));
Handle<JSFunction> fun =
- Handle<JSFunction>(stream.GetConstantFunction());
+ Handle<JSFunction>(descs->GetConstantFunction(i));
SetProperty(to, key, fun, details.attributes());
break;
}
case CALLBACKS: {
LookupResult result;
- to->LocalLookup(stream.GetKey(), &result);
+ to->LocalLookup(descs->GetKey(i), &result);
// If the property is already there we skip it
if (result.IsValid()) continue;
HandleScope inner;
Handle<DescriptorArray> inst_descs =
Handle<DescriptorArray>(to->map()->instance_descriptors());
- Handle<String> key = Handle<String>(stream.GetKey());
- Handle<Object> entry =
Handle<Object>(stream.GetCallbacksObject());
+ Handle<String> key = Handle<String>(descs->GetKey(i));
+ Handle<Object> entry =
Handle<Object>(descs->GetCallbacksObject(i));
inst_descs = Factory::CopyAppendProxyDescriptor(inst_descs,
key,
entry,
Modified: branches/bleeding_edge/src/factory.cc
==============================================================================
--- branches/bleeding_edge/src/factory.cc (original)
+++ branches/bleeding_edge/src/factory.cc Fri Jul 10 12:25:18 2009
@@ -570,13 +570,9 @@
int descriptor_count = 0;
// Copy the descriptors from the array.
- {
- DescriptorWriter w(*result);
- for (DescriptorReader r(*array); !r.eos(); r.advance()) {
- if (!r.IsNullDescriptor()) {
- w.WriteFrom(&r);
- }
- descriptor_count++;
+ for (int i = 0; i < array->number_of_descriptors(); i++) {
+ if (array->GetType(i) != NULL_DESCRIPTOR) {
+ result->CopyFrom(descriptor_count++, *array, i);
}
}
@@ -596,9 +592,6 @@
if (result->LinearSearch(*key, descriptor_count) ==
DescriptorArray::kNotFound) {
CallbacksDescriptor desc(*key, *entry, entry->property_attributes());
- // We do not use a DescriptorWriter because SymbolFromString can
- // allocate. A DescriptorWriter holds a raw pointer and is
- // therefore not GC safe.
result->Set(descriptor_count, &desc);
descriptor_count++;
} else {
@@ -609,13 +602,11 @@
// If duplicates were detected, allocate a result of the right size
// and transfer the elements.
if (duplicates > 0) {
+ int number_of_descriptors = result->number_of_descriptors() -
duplicates;
Handle<DescriptorArray> new_result =
- NewDescriptorArray(result->number_of_descriptors() - duplicates);
- DescriptorWriter w(*new_result);
- DescriptorReader r(*result);
- while (!w.eos()) {
- w.WriteFrom(&r);
- r.advance();
+ NewDescriptorArray(number_of_descriptors);
+ for (int i = 0; i < number_of_descriptors; i++) {
+ new_result->CopyFrom(i, *result, i);
}
result = new_result;
}
Modified: branches/bleeding_edge/src/handles.cc
==============================================================================
--- branches/bleeding_edge/src/handles.cc (original)
+++ branches/bleeding_edge/src/handles.cc Fri Jul 10 12:25:18 2009
@@ -289,10 +289,11 @@
// hidden symbols hash code is zero (and no other string has hash
// code zero) it will always occupy the first entry if present.
DescriptorArray* descriptors = obj->map()->instance_descriptors();
- DescriptorReader r(descriptors, 0); // Explicitly position reader at
zero.
- if (!r.eos() && (r.GetKey() == *key) && r.IsProperty()) {
- ASSERT(r.type() == FIELD);
- return Handle<Object>(obj->FastPropertyAt(r.GetFieldIndex()));
+ if ((descriptors->number_of_descriptors() > 0) &&
+ (descriptors->GetKey(0) == *key) &&
+ descriptors->IsProperty(0)) {
+ ASSERT(descriptors->GetType(0) == FIELD);
+ return
Handle<Object>(obj->FastPropertyAt(descriptors->GetFieldIndex(0)));
}
}
@@ -588,12 +589,13 @@
int num_enum = object->NumberOfEnumProperties();
Handle<FixedArray> storage = Factory::NewFixedArray(num_enum);
Handle<FixedArray> sort_array = Factory::NewFixedArray(num_enum);
- for (DescriptorReader r(object->map()->instance_descriptors());
- !r.eos();
- r.advance()) {
- if (r.IsProperty() && !r.IsDontEnum()) {
- (*storage)->set(index, r.GetKey());
- (*sort_array)->set(index, Smi::FromInt(r.GetDetails().index()));
+ Handle<DescriptorArray> descs =
+ Handle<DescriptorArray>(object->map()->instance_descriptors());
+ for (int i = 0; i < descs->number_of_descriptors(); i++) {
+ if (descs->IsProperty(i) && !descs->IsDontEnum(i)) {
+ (*storage)->set(index, descs->GetKey(i));
+ PropertyDetails details(descs->GetDetails(i));
+ (*sort_array)->set(index, Smi::FromInt(details.index()));
index++;
}
}
Modified: branches/bleeding_edge/src/objects-debug.cc
==============================================================================
--- branches/bleeding_edge/src/objects-debug.cc (original)
+++ branches/bleeding_edge/src/objects-debug.cc Fri Jul 10 12:25:18 2009
@@ -271,29 +271,38 @@
void JSObject::PrintProperties() {
if (HasFastProperties()) {
- for (DescriptorReader r(map()->instance_descriptors());
- !r.eos();
- r.advance()) {
+ DescriptorArray* descs = map()->instance_descriptors();
+ for (int i = 0; i < descs->number_of_descriptors(); i++) {
PrintF(" ");
- r.GetKey()->StringPrint();
+ descs->GetKey(i)->StringPrint();
PrintF(": ");
- if (r.type() == FIELD) {
- FastPropertyAt(r.GetFieldIndex())->ShortPrint();
- PrintF(" (field at offset %d)\n", r.GetFieldIndex());
- } else if (r.type() == CONSTANT_FUNCTION) {
- r.GetConstantFunction()->ShortPrint();
- PrintF(" (constant function)\n");
- } else if (r.type() == CALLBACKS) {
- r.GetCallbacksObject()->ShortPrint();
- PrintF(" (callback)\n");
- } else if (r.type() == MAP_TRANSITION) {
- PrintF(" (map transition)\n");
- } else if (r.type() == CONSTANT_TRANSITION) {
- PrintF(" (constant transition)\n");
- } else if (r.type() == NULL_DESCRIPTOR) {
- PrintF(" (null descriptor)\n");
- } else {
- UNREACHABLE();
+ switch (descs->GetType(i)) {
+ case FIELD: {
+ int index = descs->GetFieldIndex(i);
+ FastPropertyAt(index)->ShortPrint();
+ PrintF(" (field at offset %d)\n", index);
+ break;
+ }
+ case CONSTANT_FUNCTION:
+ descs->GetConstantFunction(i)->ShortPrint();
+ PrintF(" (constant function)\n");
+ break;
+ case CALLBACKS:
+ descs->GetCallbacksObject(i)->ShortPrint();
+ PrintF(" (callback)\n");
+ break;
+ case MAP_TRANSITION:
+ PrintF(" (map transition)\n");
+ break;
+ case CONSTANT_TRANSITION:
+ PrintF(" (constant transition)\n");
+ break;
+ case NULL_DESCRIPTOR:
+ PrintF(" (null descriptor)\n");
+ break;
+ default:
+ UNREACHABLE();
+ break;
}
}
} else {
@@ -1062,11 +1071,10 @@
void DescriptorArray::PrintDescriptors() {
PrintF("Descriptor array %d\n", number_of_descriptors());
- int number = 0;
- for (DescriptorReader r(this); !r.eos(); r.advance()) {
+ for (int i = 0; i < number_of_descriptors(); i++) {
+ PrintF(" %d: ", i);
Descriptor desc;
- r.Get(&desc);
- PrintF(" %d: ", number++);
+ Get(i, &desc);
desc.Print();
}
PrintF("\n");
@@ -1076,14 +1084,14 @@
bool DescriptorArray::IsSortedNoDuplicates() {
String* current_key = NULL;
uint32_t current = 0;
- for (DescriptorReader r(this); !r.eos(); r.advance()) {
- String* key = r.GetKey();
+ for (int i = 0; i < number_of_descriptors(); i++) {
+ String* key = GetKey(i);
if (key == current_key) {
PrintDescriptors();
return false;
}
current_key = key;
- uint32_t hash = r.GetKey()->Hash();
+ uint32_t hash = GetKey(i)->Hash();
if (hash < current) {
PrintDescriptors();
return false;
Modified: branches/bleeding_edge/src/objects-inl.h
==============================================================================
--- branches/bleeding_edge/src/objects-inl.h (original)
+++ branches/bleeding_edge/src/objects-inl.h Fri Jul 10 12:25:18 2009
@@ -1350,6 +1350,56 @@
}
+PropertyType DescriptorArray::GetType(int descriptor_number) {
+ ASSERT(descriptor_number < number_of_descriptors());
+ return PropertyDetails(GetDetails(descriptor_number)).type();
+}
+
+
+int DescriptorArray::GetFieldIndex(int descriptor_number) {
+ return Descriptor::IndexFromValue(GetValue(descriptor_number));
+}
+
+
+JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
+ return JSFunction::cast(GetValue(descriptor_number));
+}
+
+
+Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
+ ASSERT(GetType(descriptor_number) == CALLBACKS);
+ return GetValue(descriptor_number);
+}
+
+
+AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
+ ASSERT(GetType(descriptor_number) == CALLBACKS);
+ Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
+ return reinterpret_cast<AccessorDescriptor*>(p->proxy());
+}
+
+
+bool DescriptorArray::IsProperty(int descriptor_number) {
+ return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
+}
+
+
+bool DescriptorArray::IsTransition(int descriptor_number) {
+ PropertyType t = GetType(descriptor_number);
+ return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
+}
+
+
+bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
+ return GetType(descriptor_number) == NULL_DESCRIPTOR;
+}
+
+
+bool DescriptorArray::IsDontEnum(int descriptor_number) {
+ return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
+}
+
+
void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
desc->Init(GetKey(descriptor_number),
GetValue(descriptor_number),
@@ -1370,6 +1420,13 @@
fast_set(content_array, ToValueIndex(descriptor_number),
desc->GetValue());
fast_set(content_array, ToDetailsIndex(descriptor_number),
desc->GetDetails().AsSmi());
+}
+
+
+void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int
src_index) {
+ Descriptor desc;
+ src->Get(src_index, &desc);
+ Set(index, &desc);
}
Modified: branches/bleeding_edge/src/objects.cc
==============================================================================
--- branches/bleeding_edge/src/objects.cc (original)
+++ branches/bleeding_edge/src/objects.cc Fri Jul 10 12:25:18 2009
@@ -2114,20 +2114,19 @@
if (obj->IsFailure()) return obj;
StringDictionary* dictionary = StringDictionary::cast(obj);
- for (DescriptorReader r(map()->instance_descriptors());
- !r.eos();
- r.advance()) {
- PropertyDetails details = r.GetDetails();
+ DescriptorArray* descs = map()->instance_descriptors();
+ for (int i = 0; i < descs->number_of_descriptors(); i++) {
+ PropertyDetails details = descs->GetDetails(i);
switch (details.type()) {
case CONSTANT_FUNCTION: {
PropertyDetails d =
PropertyDetails(details.attributes(), NORMAL, details.index());
- Object* value = r.GetConstantFunction();
+ Object* value = descs->GetConstantFunction(i);
if (IsGlobalObject()) {
value = Heap::AllocateJSGlobalPropertyCell(value);
if (value->IsFailure()) return value;
}
- Object* result = dictionary->Add(r.GetKey(), value, d);
+ Object* result = dictionary->Add(descs->GetKey(i), value, d);
if (result->IsFailure()) return result;
dictionary = StringDictionary::cast(result);
break;
@@ -2135,12 +2134,12 @@
case FIELD: {
PropertyDetails d =
PropertyDetails(details.attributes(), NORMAL, details.index());
- Object* value = FastPropertyAt(r.GetFieldIndex());
+ Object* value = FastPropertyAt(descs->GetFieldIndex(i));
if (IsGlobalObject()) {
value = Heap::AllocateJSGlobalPropertyCell(value);
if (value->IsFailure()) return value;
}
- Object* result = dictionary->Add(r.GetKey(), value, d);
+ Object* result = dictionary->Add(descs->GetKey(i), value, d);
if (result->IsFailure()) return result;
dictionary = StringDictionary::cast(result);
break;
@@ -2148,12 +2147,12 @@
case CALLBACKS: {
PropertyDetails d =
PropertyDetails(details.attributes(), CALLBACKS,
details.index());
- Object* value = r.GetCallbacksObject();
+ Object* value = descs->GetCallbacksObject(i);
if (IsGlobalObject()) {
value = Heap::AllocateJSGlobalPropertyCell(value);
if (value->IsFailure()) return value;
}
- Object* result = dictionary->Add(r.GetKey(), value, d);
+ Object* result = dictionary->Add(descs->GetKey(i), value, d);
if (result->IsFailure()) return result;
dictionary = StringDictionary::cast(result);
break;
@@ -2567,35 +2566,44 @@
int Map::NumberOfDescribedProperties() {
int result = 0;
- for (DescriptorReader r(instance_descriptors()); !r.eos(); r.advance()) {
- if (r.IsProperty()) result++;
+ DescriptorArray* descs = instance_descriptors();
+ for (int i = 0; i < descs->number_of_descriptors(); i++) {
+ if (descs->IsProperty(i)) result++;
}
return result;
}
int Map::PropertyIndexFor(String* name) {
- for (DescriptorReader r(instance_descriptors()); !r.eos(); r.advance()) {
- if (r.Equals(name) && !r.IsNullDescriptor()) return r.GetFieldIndex();
+ DescriptorArray* descs = instance_descriptors();
+ for (int i = 0; i < descs->number_of_descriptors(); i++) {
+ if (name->Equals(descs->GetKey(i)) && !descs->IsNullDescriptor(i)) {
+ return descs->GetFieldIndex(i);
+ }
}
return -1;
}
int Map::NextFreePropertyIndex() {
- int index = -1;
- for (DescriptorReader r(instance_descriptors()); !r.eos(); r.advance()) {
- if (r.type() == FIELD) {
- if (r.GetFieldIndex() > index) index = r.GetFieldIndex();
+ int max_index = -1;
+ DescriptorArray* descs = instance_descriptors();
+ for (int i = 0; i < descs->number_of_descriptors(); i++) {
+ if (descs->GetType(i) == FIELD) {
+ int current_index = descs->GetFieldIndex(i);
+ if (current_index > max_index) max_index = current_index;
}
}
- return index+1;
+ return max_index + 1;
}
AccessorDescriptor* Map::FindAccessor(String* name) {
- for (DescriptorReader r(instance_descriptors()); !r.eos(); r.advance()) {
- if (r.Equals(name) && r.type() == CALLBACKS) return r.GetCallbacks();
+ DescriptorArray* descs = instance_descriptors();
+ for (int i = 0; i < descs->number_of_descriptors(); i++) {
+ if (name->Equals(descs->GetKey(i)) && descs->GetType(i) == CALLBACKS) {
+ return descs->GetCallbacks(i);
+ }
}
return NULL;
}
@@ -2843,16 +2851,15 @@
Object* JSObject::SlowReverseLookup(Object* value) {
if (HasFastProperties()) {
- for (DescriptorReader r(map()->instance_descriptors());
- !r.eos();
- r.advance()) {
- if (r.type() == FIELD) {
- if (FastPropertyAt(r.GetFieldIndex()) == value) {
- return r.GetKey();
+ DescriptorArray* descs = map()->instance_descriptors();
+ for (int i = 0; i < descs->number_of_descriptors(); i++) {
+ if (descs->GetType(i) == FIELD) {
+ if (FastPropertyAt(descs->GetFieldIndex(i)) == value) {
+ return descs->GetKey(i);
}
- } else if (r.type() == CONSTANT_FUNCTION) {
- if (r.GetConstantFunction() == value) {
- return r.GetKey();
+ } else if (descs->GetType(i) == CONSTANT_FUNCTION) {
+ if (descs->GetConstantFunction(i) == value) {
+ return descs->GetKey(i);
}
}
}
@@ -3166,13 +3173,13 @@
int transitions = 0;
int null_descriptors = 0;
if (remove_transitions) {
- for (DescriptorReader r(this); !r.eos(); r.advance()) {
- if (r.IsTransition()) transitions++;
- if (r.IsNullDescriptor()) null_descriptors++;
+ for (int i = 0; i < number_of_descriptors(); i++) {
+ if (IsTransition(i)) transitions++;
+ if (IsNullDescriptor(i)) null_descriptors++;
}
} else {
- for (DescriptorReader r(this); !r.eos(); r.advance()) {
- if (r.IsNullDescriptor()) null_descriptors++;
+ for (int i = 0; i < number_of_descriptors(); i++) {
+ if (IsNullDescriptor(i)) null_descriptors++;
}
}
int new_size = number_of_descriptors() - transitions - null_descriptors;
@@ -3220,32 +3227,31 @@
// Copy the descriptors, filtering out transitions and null descriptors,
// and inserting or replacing a descriptor.
- DescriptorWriter w(new_descriptors);
- DescriptorReader r(this);
uint32_t descriptor_hash = descriptor->GetKey()->Hash();
+ int from_index = 0;
+ int to_index = 0;
- for (; !r.eos(); r.advance()) {
- if (r.GetKey()->Hash() > descriptor_hash ||
- r.GetKey() == descriptor->GetKey()) break;
- if (r.IsNullDescriptor()) continue;
- if (remove_transitions && r.IsTransition()) continue;
- w.WriteFrom(&r);
+ for (; from_index < number_of_descriptors(); from_index++) {
+ String* key = GetKey(from_index);
+ if (key->Hash() > descriptor_hash || key == descriptor->GetKey()) {
+ break;
+ }
+ if (IsNullDescriptor(from_index)) continue;
+ if (remove_transitions && IsTransition(from_index)) continue;
+ new_descriptors->CopyFrom(to_index++, this, from_index);
}
- w.Write(descriptor);
- if (replacing) {
- ASSERT(r.GetKey() == descriptor->GetKey());
- r.advance();
- } else {
- ASSERT(r.eos() ||
- r.GetKey()->Hash() > descriptor_hash ||
- r.IsNullDescriptor());
- }
- for (; !r.eos(); r.advance()) {
- if (r.IsNullDescriptor()) continue;
- if (remove_transitions && r.IsTransition()) continue;
- w.WriteFrom(&r);
+
+ new_descriptors->Set(to_index++, descriptor);
+ if (replacing) from_index++;
+
+ for (; from_index < number_of_descriptors(); from_index++) {
+ if (IsNullDescriptor(from_index)) continue;
+ if (remove_transitions && IsTransition(from_index)) continue;
+ new_descriptors->CopyFrom(to_index++, this, from_index);
}
- ASSERT(w.eos());
+
+ ASSERT(to_index == new_descriptors->number_of_descriptors());
+ SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates());
return new_descriptors;
}
@@ -3258,8 +3264,8 @@
// Compute the size of the map transition entries to be removed.
int num_removed = 0;
- for (DescriptorReader r(this); !r.eos(); r.advance()) {
- if (!r.IsProperty()) num_removed++;
+ for (int i = 0; i < number_of_descriptors(); i++) {
+ if (!IsProperty(i)) num_removed++;
}
// Allocate the new descriptor array.
@@ -3268,11 +3274,11 @@
DescriptorArray* new_descriptors = DescriptorArray::cast(result);
// Copy the content.
- DescriptorWriter w(new_descriptors);
- for (DescriptorReader r(this); !r.eos(); r.advance()) {
- if (r.IsProperty()) w.WriteFrom(&r);
+ int next_descriptor = 0;
+ for (int i = 0; i < number_of_descriptors(); i++) {
+ if (IsProperty(i)) new_descriptors->CopyFrom(next_descriptor++, this,
i);
}
- ASSERT(w.eos());
+ ASSERT(next_descriptor == new_descriptors->number_of_descriptors());
return new_descriptors;
}
@@ -4579,10 +4585,10 @@
void Map::CreateBackPointers() {
DescriptorArray* descriptors = instance_descriptors();
- for (DescriptorReader r(descriptors); !r.eos(); r.advance()) {
- if (r.type() == MAP_TRANSITION) {
+ for (int i = 0; i < descriptors->number_of_descriptors(); i++) {
+ if (descriptors->GetType(i) == MAP_TRANSITION) {
// Get target.
- Map* target = Map::cast(r.GetValue());
+ Map* target = Map::cast(descriptors->GetValue(i));
#ifdef DEBUG
// Verify target.
Object* source_prototype = prototype();
@@ -4593,7 +4599,7 @@
ASSERT(target_prototype->IsJSObject() ||
target_prototype->IsNull());
ASSERT(source_prototype->IsMap() ||
- source_prototype == target_prototype);
+ source_prototype == target_prototype);
#endif
// Point target back to source. set_prototype() will not let us set
// the prototype to a map, as we do here.
@@ -6011,13 +6017,11 @@
int JSObject::NumberOfLocalProperties(PropertyAttributes filter) {
if (HasFastProperties()) {
+ DescriptorArray* descs = map()->instance_descriptors();
int result = 0;
- for (DescriptorReader r(map()->instance_descriptors());
- !r.eos();
- r.advance()) {
- PropertyDetails details = r.GetDetails();
- if (details.IsProperty() &&
- (details.attributes() & filter) == 0) {
+ for (int i = 0; i < descs->number_of_descriptors(); i++) {
+ PropertyDetails details = descs->GetDetails(i);
+ if (details.IsProperty() && (details.attributes() & filter) == 0) {
result++;
}
}
@@ -6150,16 +6154,11 @@
// purpose of this function is to provide reflection information for the
object
// mirrors.
void JSObject::GetLocalPropertyNames(FixedArray* storage, int index) {
- ASSERT(storage->length() >=
- NumberOfLocalProperties(static_cast<PropertyAttributes>(NONE)) -
- index);
+ ASSERT(storage->length() >= (NumberOfLocalProperties(NONE) - index));
if (HasFastProperties()) {
- for (DescriptorReader r(map()->instance_descriptors());
- !r.eos();
- r.advance()) {
- if (r.IsProperty()) {
- storage->set(index++, r.GetKey());
- }
+ DescriptorArray* descs = map()->instance_descriptors();
+ for (int i = 0; i < descs->number_of_descriptors(); i++) {
+ if (descs->IsProperty(i)) storage->set(index++, descs->GetKey(i));
}
ASSERT(storage->length() >= index);
} else {
@@ -7428,7 +7427,7 @@
if (fields->IsFailure()) return fields;
// Fill in the instance descriptor and the fields.
- DescriptorWriter w(descriptors);
+ int next_descriptor = 0;
int current_offset = 0;
for (int i = 0; i < capacity; i++) {
Object* k = KeyAt(i);
@@ -7445,7 +7444,7 @@
JSFunction::cast(value),
details.attributes(),
details.index());
- w.Write(&d);
+ descriptors->Set(next_descriptor++, &d);
} else if (type == NORMAL) {
if (current_offset < inobject_props) {
obj->InObjectPropertyAtPut(current_offset,
@@ -7459,13 +7458,13 @@
current_offset++,
details.attributes(),
details.index());
- w.Write(&d);
+ descriptors->Set(next_descriptor++, &d);
} else if (type == CALLBACKS) {
CallbacksDescriptor d(String::cast(key),
value,
details.attributes(),
details.index());
- w.Write(&d);
+ descriptors->Set(next_descriptor++, &d);
} else {
UNREACHABLE();
}
Modified: branches/bleeding_edge/src/objects.h
==============================================================================
--- branches/bleeding_edge/src/objects.h (original)
+++ branches/bleeding_edge/src/objects.h Fri Jul 10 12:25:18 2009
@@ -1850,14 +1850,27 @@
// using the supplied storage for the small "bridge".
void SetEnumCache(FixedArray* bridge_storage, FixedArray* new_cache);
- // Accessors for fetching instance descriptor at descriptor number..
+ // Accessors for fetching instance descriptor at descriptor number.
inline String* GetKey(int descriptor_number);
inline Object* GetValue(int descriptor_number);
inline Smi* GetDetails(int descriptor_number);
+ inline PropertyType GetType(int descriptor_number);
+ inline int GetFieldIndex(int descriptor_number);
+ inline JSFunction* GetConstantFunction(int descriptor_number);
+ inline Object* GetCallbacksObject(int descriptor_number);
+ inline AccessorDescriptor* GetCallbacks(int descriptor_number);
+ inline bool IsProperty(int descriptor_number);
+ inline bool IsTransition(int descriptor_number);
+ inline bool IsNullDescriptor(int descriptor_number);
+ inline bool IsDontEnum(int descriptor_number);
// Accessor for complete descriptor.
inline void Get(int descriptor_number, Descriptor* desc);
inline void Set(int descriptor_number, Descriptor* desc);
+
+ // Transfer complete descriptor from another descriptor array to
+ // this one.
+ inline void CopyFrom(int index, DescriptorArray* src, int src_index);
// Copy the descriptor array, insert a new descriptor and optionally
// remove map transitions. If the descriptor is already present, it is
Modified: branches/bleeding_edge/src/property.cc
==============================================================================
--- branches/bleeding_edge/src/property.cc (original)
+++ branches/bleeding_edge/src/property.cc Fri Jul 10 12:25:18 2009
@@ -31,20 +31,6 @@
namespace internal {
-void DescriptorWriter::Write(Descriptor* desc) {
- ASSERT(desc->key_->IsSymbol());
- descriptors_->Set(pos_, desc);
- advance();
-}
-
-
-void DescriptorWriter::WriteFrom(DescriptorReader* reader) {
- Descriptor desc;
- reader->Get(&desc);
- Write(&desc);
-}
-
-
#ifdef DEBUG
void LookupResult::Print() {
if (!IsValid()) {
Modified: branches/bleeding_edge/src/property.h
==============================================================================
--- branches/bleeding_edge/src/property.h (original)
+++ branches/bleeding_edge/src/property.h Fri Jul 10 12:25:18 2009
@@ -95,8 +95,6 @@
value_(value),
details_(attributes, type, index) { }
- friend class DescriptorWriter;
- friend class DescriptorReader;
friend class DescriptorArray;
};
@@ -323,92 +321,6 @@
PropertyDetails details_;
};
-
-// The DescriptorStream is an abstraction for iterating over a map's
-// instance descriptors.
-class DescriptorStream BASE_EMBEDDED {
- public:
- explicit DescriptorStream(DescriptorArray* descriptors, int pos) {
- descriptors_ = descriptors;
- pos_ = pos;
- limit_ = descriptors_->number_of_descriptors();
- }
-
- // Tells whether we have reached the end of the steam.
- bool eos() { return pos_ >= limit_; }
-
- int next_position() { return pos_ + 1; }
- void advance() { pos_ = next_position(); }
-
- protected:
- DescriptorArray* descriptors_;
- int pos_; // Current position.
- int limit_; // Limit for position.
-};
-
-
-class DescriptorReader: public DescriptorStream {
- public:
- explicit DescriptorReader(DescriptorArray* descriptors, int pos = 0)
- : DescriptorStream(descriptors, pos) {}
-
- String* GetKey() { return descriptors_->GetKey(pos_); }
- Object* GetValue() { return descriptors_->GetValue(pos_); }
- PropertyDetails GetDetails() {
- return PropertyDetails(descriptors_->GetDetails(pos_));
- }
-
- int GetFieldIndex() { return Descriptor::IndexFromValue(GetValue()); }
-
- bool IsDontEnum() { return GetDetails().IsDontEnum(); }
-
- PropertyType type() { return GetDetails().type(); }
-
- // Tells whether the type is a transition.
- bool IsTransition() {
- PropertyType t = type();
- ASSERT(t != INTERCEPTOR);
- return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
- }
-
- bool IsNullDescriptor() {
- return type() == NULL_DESCRIPTOR;
- }
-
- bool IsProperty() {
- return type() < FIRST_PHANTOM_PROPERTY_TYPE;
- }
-
- JSFunction* GetConstantFunction() { return JSFunction::cast(GetValue());
}
-
- AccessorDescriptor* GetCallbacks() {
- ASSERT(type() == CALLBACKS);
- Proxy* p = Proxy::cast(GetCallbacksObject());
- return reinterpret_cast<AccessorDescriptor*>(p->proxy());
- }
-
- Object* GetCallbacksObject() {
- ASSERT(type() == CALLBACKS);
- return GetValue();
- }
-
- bool Equals(String* name) { return name->Equals(GetKey()); }
-
- void Get(Descriptor* desc) {
- descriptors_->Get(pos_, desc);
- }
-};
-
-class DescriptorWriter: public DescriptorStream {
- public:
- explicit DescriptorWriter(DescriptorArray* descriptors)
- : DescriptorStream(descriptors, 0) {}
-
- // Append a descriptor to this stream.
- void Write(Descriptor* desc);
- // Read a descriptor from the reader and append it to this stream.
- void WriteFrom(DescriptorReader* reader);
-};
} } // namespace v8::internal
Modified: branches/bleeding_edge/src/spaces.cc
==============================================================================
--- branches/bleeding_edge/src/spaces.cc (original)
+++ branches/bleeding_edge/src/spaces.cc Fri Jul 10 12:25:18 2009
@@ -37,8 +37,8 @@
// For contiguous spaces, top should be in the space (or at the end) and
limit
// should be the end of the space.
#define ASSERT_SEMISPACE_ALLOCATION_INFO(info, space) \
- ASSERT((space).low() <= (info).top \
- && (info).top <= (space).high() \
+ ASSERT((space).low() <= (info).top \
+ && (info).top <= (space).high() \
&& (info).limit == (space).high())
Modified: branches/bleeding_edge/src/string-stream.cc
==============================================================================
--- branches/bleeding_edge/src/string-stream.cc (original)
+++ branches/bleeding_edge/src/string-stream.cc Fri Jul 10 12:25:18 2009
@@ -343,10 +343,11 @@
Add("<Invalid map>\n");
return;
}
- for (DescriptorReader r(map->instance_descriptors()); !r.eos();
r.advance()) {
- switch (r.type()) {
+ DescriptorArray* descs = map->instance_descriptors();
+ for (int i = 0; i < descs->number_of_descriptors(); i++) {
+ switch (descs->GetType(i)) {
case FIELD: {
- Object* key = r.GetKey();
+ Object* key = descs->GetKey(i);
if (key->IsString() || key->IsNumber()) {
int len = 3;
if (key->IsString()) {
@@ -360,7 +361,7 @@
key->ShortPrint();
}
Add(": ");
- Object* value = js_object->FastPropertyAt(r.GetFieldIndex());
+ Object* value =
js_object->FastPropertyAt(descs->GetFieldIndex(i));
Add("%o\n", value);
}
}
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---