Commit 67d531c3 authored by verwaest's avatar verwaest Committed by Commit bot

Don't double-allocate mutable heap numbers in the json parser. This removes...

Don't double-allocate mutable heap numbers in the json parser. This removes some stupidity when committing state.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#27034}
parent a8e82da6
...@@ -300,6 +300,7 @@ Handle<Object> JsonParser<seq_one_byte>::ParseJsonObject() { ...@@ -300,6 +300,7 @@ Handle<Object> JsonParser<seq_one_byte>::ParseJsonObject() {
Handle<JSObject> json_object = Handle<JSObject> json_object =
factory()->NewJSObject(object_constructor(), pretenure_); factory()->NewJSObject(object_constructor(), pretenure_);
Handle<Map> map(json_object->map()); Handle<Map> map(json_object->map());
int descriptor = 0;
ZoneList<Handle<Object> > properties(8, zone()); ZoneList<Handle<Object> > properties(8, zone());
DCHECK_EQ(c0_, '{'); DCHECK_EQ(c0_, '{');
...@@ -382,18 +383,15 @@ Handle<Object> JsonParser<seq_one_byte>::ParseJsonObject() { ...@@ -382,18 +383,15 @@ Handle<Object> JsonParser<seq_one_byte>::ParseJsonObject() {
if (value.is_null()) return ReportUnexpectedCharacter(); if (value.is_null()) return ReportUnexpectedCharacter();
if (transitioning) { if (transitioning) {
int descriptor = map->NumberOfOwnDescriptors();
PropertyDetails details = PropertyDetails details =
target->instance_descriptors()->GetDetails(descriptor); target->instance_descriptors()->GetDetails(descriptor);
Representation expected_representation = details.representation(); Representation expected_representation = details.representation();
if (value->FitsRepresentation(expected_representation)) { if (value->FitsRepresentation(expected_representation)) {
if (expected_representation.IsDouble()) { if (expected_representation.IsHeapObject() &&
value = Object::NewStorageFor(isolate(), value, !target->instance_descriptors()
expected_representation); ->GetFieldType(descriptor)
} else if (expected_representation.IsHeapObject() && ->NowContains(value)) {
!target->instance_descriptors()->GetFieldType(
descriptor)->NowContains(value)) {
Handle<HeapType> value_type(value->OptimalType( Handle<HeapType> value_type(value->OptimalType(
isolate(), expected_representation)); isolate(), expected_representation));
Map::GeneralizeFieldType(target, descriptor, Map::GeneralizeFieldType(target, descriptor,
...@@ -403,6 +401,7 @@ Handle<Object> JsonParser<seq_one_byte>::ParseJsonObject() { ...@@ -403,6 +401,7 @@ Handle<Object> JsonParser<seq_one_byte>::ParseJsonObject() {
descriptor)->NowContains(value)); descriptor)->NowContains(value));
properties.Add(value, zone()); properties.Add(value, zone());
map = target; map = target;
descriptor++;
continue; continue;
} else { } else {
transitioning = false; transitioning = false;
...@@ -444,30 +443,11 @@ void JsonParser<seq_one_byte>::CommitStateToJsonObject( ...@@ -444,30 +443,11 @@ void JsonParser<seq_one_byte>::CommitStateToJsonObject(
DCHECK(!json_object->map()->is_dictionary_map()); DCHECK(!json_object->map()->is_dictionary_map());
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
Factory* factory = isolate()->factory();
// If the |json_object|'s map is exactly the same as |map| then the
// |properties| values correspond to the |map| and nothing more has to be
// done. But if the |json_object|'s map is different then we have to
// iterate descriptors to ensure that properties still correspond to the
// map.
bool slow_case = json_object->map() != *map;
DescriptorArray* descriptors = NULL;
int length = properties->length(); int length = properties->length();
if (slow_case) {
descriptors = json_object->map()->instance_descriptors();
DCHECK(json_object->map()->NumberOfOwnDescriptors() == length);
}
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
Handle<Object> value = (*properties)[i]; Handle<Object> value = (*properties)[i];
if (slow_case && value->IsMutableHeapNumber() && json_object->WriteToField(i, *value);
!descriptors->GetDetails(i).representation().IsDouble()) {
// Turn mutable heap numbers into immutable if the field representation
// is not double.
HeapNumber::cast(*value)->set_map(*factory->heap_number_map());
}
FieldIndex index = FieldIndex::ForPropertyIndex(*map, i);
json_object->FastPropertyAtPut(index, *value);
} }
} }
......
...@@ -2139,6 +2139,31 @@ void JSObject::FastPropertyAtPut(FieldIndex index, Object* value) { ...@@ -2139,6 +2139,31 @@ void JSObject::FastPropertyAtPut(FieldIndex index, Object* value) {
} }
void JSObject::WriteToField(int descriptor, Object* value) {
DisallowHeapAllocation no_gc;
DescriptorArray* desc = map()->instance_descriptors();
PropertyDetails details = desc->GetDetails(descriptor);
DCHECK(details.type() == DATA);
FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor);
if (details.representation().IsDouble()) {
// Nothing more to be done.
if (value->IsUninitialized()) return;
if (IsUnboxedDoubleField(index)) {
RawFastDoublePropertyAtPut(index, value->Number());
} else {
HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index));
DCHECK(box->IsMutableHeapNumber());
box->set_value(value->Number());
}
} else {
RawFastPropertyAtPut(index, value);
}
}
int JSObject::GetInObjectPropertyOffset(int index) { int JSObject::GetInObjectPropertyOffset(int index) {
return map()->GetInObjectPropertyOffset(index); return map()->GetInObjectPropertyOffset(index);
} }
......
...@@ -4127,31 +4127,6 @@ bool JSObject::TryMigrateInstance(Handle<JSObject> object) { ...@@ -4127,31 +4127,6 @@ bool JSObject::TryMigrateInstance(Handle<JSObject> object) {
} }
void JSObject::WriteToField(int descriptor, Object* value) {
DisallowHeapAllocation no_gc;
DescriptorArray* desc = map()->instance_descriptors();
PropertyDetails details = desc->GetDetails(descriptor);
DCHECK(details.type() == DATA);
FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor);
if (details.representation().IsDouble()) {
// Nothing more to be done.
if (value->IsUninitialized()) return;
if (IsUnboxedDoubleField(index)) {
RawFastDoublePropertyAtPut(index, value->Number());
} else {
HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index));
DCHECK(box->IsMutableHeapNumber());
box->set_value(value->Number());
}
} else {
RawFastPropertyAtPut(index, value);
}
}
void JSObject::AddProperty(Handle<JSObject> object, Handle<Name> name, void JSObject::AddProperty(Handle<JSObject> object, Handle<Name> name,
Handle<Object> value, Handle<Object> value,
PropertyAttributes attributes) { PropertyAttributes attributes) {
......
...@@ -2080,7 +2080,7 @@ class JSObject: public JSReceiver { ...@@ -2080,7 +2080,7 @@ class JSObject: public JSReceiver {
inline void FastPropertyAtPut(FieldIndex index, Object* value); inline void FastPropertyAtPut(FieldIndex index, Object* value);
inline void RawFastPropertyAtPut(FieldIndex index, Object* value); inline void RawFastPropertyAtPut(FieldIndex index, Object* value);
inline void RawFastDoublePropertyAtPut(FieldIndex index, double value); inline void RawFastDoublePropertyAtPut(FieldIndex index, double value);
void WriteToField(int descriptor, Object* value); inline void WriteToField(int descriptor, Object* value);
// Access to in object properties. // Access to in object properties.
inline int GetInObjectPropertyOffset(int index); inline int GetInObjectPropertyOffset(int index);
......
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