Chromium Code Reviews| Index: src/json-parser.h |
| diff --git a/src/json-parser.h b/src/json-parser.h |
| index 78c1a7a4e0ddb5e90e756bf80b7d8eefff880253..8092e58170a83ebc58b97339c7b64187619631ab 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::TransitionToMap(json_object, map); |
|
danno
2013/05/07 13:04:47
AllocateStorageForMap... better name?
Toon Verwaest
2013/05/07 15:08:52
Done.
|
| + int length = properties.length(); |
| + for (int i = 0; i < length; i++) { |
| + Handle<Object> value = properties[i]; |
| + json_object->FastPropertyAtPut(i, *value); |
| } |
| } else { |
| key = ParseJsonInternalizedString(); |
| @@ -454,10 +457,15 @@ Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() { |
| 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); |
| } |