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

Unified Diff: src/objects.cc

Issue 18096: Experimental: merge from bleeding_edge. Merge up to and including... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: Created 11 years, 11 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/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
===================================================================
--- src/objects.cc (revision 1085)
+++ src/objects.cc (working copy)
@@ -43,6 +43,22 @@
namespace v8 { namespace internal {
+#define FIELD_ADDR(p, offset) \
+ (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
+
+
+#define WRITE_FIELD(p, offset, value) \
+ (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
+
+
+#define WRITE_INT_FIELD(p, offset, value) \
+ (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
+
+
+#define WRITE_BARRIER(object, offset) \
+ Heap::RecordWrite(object->address(), offset);
+
+
// Getters and setters are stored in a fixed array property. These are
// constants for their indices.
const int kGetterIndex = 0;
@@ -924,6 +940,7 @@
reinterpret_cast<FixedArray*>(this)->FixedArrayIterateBody(v);
break;
case JS_OBJECT_TYPE:
+ case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
case JS_VALUE_TYPE:
case JS_ARRAY_TYPE:
case JS_REGEXP_TYPE:
@@ -1040,7 +1057,7 @@
// Normalize the object if the name is not a real identifier.
StringInputBuffer buffer(name);
if (!Scanner::IsIdentifier(&buffer)) {
- Object* obj = NormalizeProperties();
+ Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES);
if (obj->IsFailure()) return obj;
return AddSlowProperty(name, value, attributes);
}
@@ -1078,7 +1095,7 @@
if (map()->unused_property_fields() == 0) {
if (properties()->length() > kMaxFastProperties) {
- Object* obj = NormalizeProperties();
+ Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES);
if (obj->IsFailure()) return obj;
return AddSlowProperty(name, value, attributes);
}
@@ -1180,7 +1197,7 @@
} else {
// Normalize the object to prevent very large instance descriptors.
// This eliminates unwanted N^2 allocation and lookup behavior.
- Object* obj = NormalizeProperties();
+ Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES);
if (obj->IsFailure()) return obj;
}
}
@@ -1253,7 +1270,7 @@
PropertyAttributes attributes) {
if (map()->unused_property_fields() == 0 &&
properties()->length() > kMaxFastProperties) {
- Object* obj = NormalizeProperties();
+ Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES);
if (obj->IsFailure()) return obj;
return ReplaceSlowProperty(name, new_value, attributes);
}
@@ -1582,7 +1599,7 @@
return JSObject::cast(proto)->SetProperty(result, name, value, attributes);
}
- if (result->IsNotFound() || !result->IsProperty()) {
+ if (!result->IsProperty() && !IsJSContextExtensionObject()) {
// We could not find a local property so let's check whether there is an
// accessor that wants to handle the property.
LookupResult accessor_result;
@@ -1848,7 +1865,7 @@
}
-Object* JSObject::NormalizeProperties() {
+Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode) {
if (!HasFastProperties()) return this;
// Allocate new content
@@ -1908,13 +1925,33 @@
// Allocate new map.
obj = map()->Copy();
if (obj->IsFailure()) return obj;
+ Map* new_map = Map::cast(obj);
+ // Clear inobject properties if needed by adjusting the instance
+ // size and putting in a filler or byte array instead of the
+ // inobject properties.
+ if (mode == CLEAR_INOBJECT_PROPERTIES && map()->inobject_properties() > 0) {
+ int instance_size_delta = map()->inobject_properties() * kPointerSize;
+ int new_instance_size = map()->instance_size() - instance_size_delta;
+ new_map->set_inobject_properties(0);
+ new_map->set_instance_size(new_instance_size);
+ if (instance_size_delta == kPointerSize) {
+ WRITE_FIELD(this, new_instance_size, Heap::one_word_filler_map());
+ } else {
+ int byte_array_length = ByteArray::LengthFor(instance_size_delta);
+ int byte_array_length_offset = new_instance_size + kPointerSize;
+ WRITE_FIELD(this, new_instance_size, Heap::byte_array_map());
+ WRITE_INT_FIELD(this, byte_array_length_offset, byte_array_length);
+ }
+ WRITE_BARRIER(this, new_instance_size);
+ }
+ new_map->set_unused_property_fields(0);
+
// We have now sucessfully allocated all the necessary objects.
// Changes can now be made with the guarantee that all of them take effect.
- set_map(Map::cast(obj));
+ set_map(new_map);
map()->set_instance_descriptors(Heap::empty_descriptor_array());
- map()->set_unused_property_fields(0);
set_properties(dictionary);
Counters::props_to_dictionary.Increment();
@@ -1982,7 +2019,7 @@
if (!result.IsValid()) return Heap::true_value();
// Normalize object if needed.
- Object* obj = NormalizeProperties();
+ Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES);
if (obj->IsFailure()) return obj;
ASSERT(!HasFastProperties());
@@ -2145,7 +2182,7 @@
return JSObject::cast(this)->DeleteLazyProperty(&result, name);
}
// Normalize object if needed.
- Object* obj = NormalizeProperties();
+ Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES);
if (obj->IsFailure()) return obj;
// Make sure the properties are normalized before removing the entry.
Dictionary* dictionary = property_dictionary();
@@ -2324,7 +2361,7 @@
}
// Check __proto__ before interceptor.
- if (name->Equals(Heap::Proto_symbol())) {
+ if (name->Equals(Heap::Proto_symbol()) && !IsJSContextExtensionObject()) {
result->ConstantResult(this);
return;
}
@@ -2411,7 +2448,7 @@
}
// Normalize object to make this operation simple.
- Object* ok = NormalizeProperties();
+ Object* ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES);
if (ok->IsFailure()) return ok;
// Allocate the fixed array to hold getter and setter.
@@ -6664,7 +6701,9 @@
if (descriptors_unchecked->IsFailure()) return descriptors_unchecked;
DescriptorArray* descriptors = DescriptorArray::cast(descriptors_unchecked);
- int number_of_allocated_fields = number_of_fields + unused_property_fields;
+ int inobject_props = obj->map()->inobject_properties();
+ int number_of_allocated_fields =
+ number_of_fields + unused_property_fields - inobject_props;
// Allocate the fixed array for the fields.
Object* fields = Heap::AllocateFixedArray(number_of_allocated_fields);
@@ -6682,6 +6721,7 @@
if (key->IsFailure()) return key;
PropertyDetails details = DetailsAt(i);
PropertyType type = details.type();
+
if (value->IsJSFunction()) {
ConstantFunctionDescriptor d(String::cast(key),
JSFunction::cast(value),
@@ -6689,7 +6729,14 @@
details.index());
w.Write(&d);
} else if (type == NORMAL) {
- FixedArray::cast(fields)->set(current_offset, value);
+ if (current_offset < inobject_props) {
+ obj->InObjectPropertyAtPut(current_offset,
+ value,
+ UPDATE_WRITE_BARRIER);
+ } else {
+ int offset = current_offset - inobject_props;
+ FixedArray::cast(fields)->set(offset, value);
+ }
FieldDescriptor d(String::cast(key),
current_offset++,
details.attributes(),
@@ -6722,8 +6769,9 @@
ASSERT(obj->IsJSObject());
descriptors->SetNextEnumerationIndex(NextEnumerationIndex());
- // Check it really works.
+ // Check that it really works.
ASSERT(obj->HasFastProperties());
+
return obj;
}
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698