| Index: src/json-parser.h
|
| diff --git a/src/json-parser.h b/src/json-parser.h
|
| index 78c1a7a4e0ddb5e90e756bf80b7d8eefff880253..ddc3b736e3624aa556c46798bb13e49842ff87be 100644
|
| --- a/src/json-parser.h
|
| +++ b/src/json-parser.h
|
| @@ -381,39 +381,23 @@ Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() {
|
| // First check whether there is a single expected transition. If so, try
|
| // to parse it first.
|
| bool follow_expected = false;
|
| + Handle<Map> target;
|
| if (seq_ascii) {
|
| key = JSObject::ExpectedTransitionKey(map);
|
| follow_expected = !key.is_null() && ParseJsonString(key);
|
| }
|
| // If the expected transition hits, follow it.
|
| if (follow_expected) {
|
| - map = JSObject::ExpectedTransitionTarget(map);
|
| + target = JSObject::ExpectedTransitionTarget(map);
|
| } else {
|
| // If the expected transition failed, parse an internalized string and
|
| // try to find a matching transition.
|
| key = ParseJsonInternalizedString();
|
| if (key.is_null()) return ReportUnexpectedCharacter();
|
|
|
| - Handle<Map> target = JSObject::FindTransitionToField(map, key);
|
| + target = JSObject::FindTransitionToField(map, key);
|
| // If a transition was found, follow it and continue.
|
| - if (!target.is_null()) {
|
| - map = target;
|
| - } else {
|
| - // If no transition was found, commit the intermediate state to the
|
| - // object and stop transitioning.
|
| - JSObject::TransitionToMap(json_object, map);
|
| - int length = properties.length();
|
| - for (int i = 0; i < length; i++) {
|
| - Handle<Object> value = properties[i];
|
| - Representation representation =
|
| - map->instance_descriptors()->GetDetails(i).representation();
|
| - if (representation.IsDouble() && value->IsSmi()) {
|
| - // TODO(verwaest): Allocate heap number.
|
| - }
|
| - json_object->FastPropertyAtPut(i, *value);
|
| - }
|
| - transitioning = false;
|
| - }
|
| + transitioning = !target.is_null();
|
| }
|
| if (c0_ != ':') return ReportUnexpectedCharacter();
|
|
|
| @@ -421,16 +405,35 @@ Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() {
|
| value = ParseJsonValue();
|
| if (value.is_null()) return ReportUnexpectedCharacter();
|
|
|
| - properties.Add(value, zone());
|
| if (transitioning) {
|
| - int field = properties.length() - 1;
|
| - Representation expected_representation =
|
| - map->instance_descriptors()->GetDetails(field).representation();
|
| - if (!value->FitsRepresentation(expected_representation)) {
|
| - map = Map::GeneralizeRepresentation(
|
| - map, field, value->OptimalRepresentation());
|
| + int descriptor = map->NumberOfOwnDescriptors();
|
| + PropertyDetails details =
|
| + target->instance_descriptors()->GetDetails(descriptor);
|
| + Representation expected_representation = details.representation();
|
| +
|
| + if (value->FitsRepresentation(expected_representation)) {
|
| + // If the target representation is double and the value is already
|
| + // double, use the existing box.
|
| + if (FLAG_track_double_fields &&
|
| + value->IsSmi() &&
|
| + expected_representation.IsDouble()) {
|
| + value = factory()->NewHeapNumber(
|
| + Handle<Smi>::cast(value)->value());
|
| + }
|
| + properties.Add(value, zone());
|
| + map = target;
|
| + continue;
|
| + } else {
|
| + transitioning = false;
|
| }
|
| - continue;
|
| + }
|
| +
|
| + // Commit the intermediate state to the object and stop transitioning.
|
| + JSObject::AllocateStorageForMap(json_object, map);
|
| + int length = properties.length();
|
| + for (int i = 0; i < length; i++) {
|
| + Handle<Object> value = properties[i];
|
| + json_object->FastPropertyAtPut(i, *value);
|
| }
|
| } else {
|
| key = ParseJsonInternalizedString();
|
| @@ -450,14 +453,19 @@ Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() {
|
|
|
| // If we transitioned until the very end, transition the map now.
|
| if (transitioning) {
|
| - JSObject::TransitionToMap(json_object, map);
|
| + JSObject::AllocateStorageForMap(json_object, map);
|
| int length = properties.length();
|
| for (int i = 0; i < length; i++) {
|
| Handle<Object> value = properties[i];
|
| - Representation representation =
|
| - map->instance_descriptors()->GetDetails(i).representation();
|
| - if (representation.IsDouble() && value->IsSmi()) {
|
| - // TODO(verwaest): Allocate heap number.
|
| + // If the target representation is double and the value is already
|
| + // double, use the existing box.
|
| + if (FLAG_track_double_fields && value->IsSmi()) {
|
| + Representation representation =
|
| + map->instance_descriptors()->GetDetails(i).representation();
|
| + if (representation.IsDouble()) {
|
| + value = factory()->NewHeapNumber(
|
| + Handle<Smi>::cast(value)->value());
|
| + }
|
| }
|
| json_object->FastPropertyAtPut(i, *value);
|
| }
|
|
|