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); |
} |