Eagerly follow transitions to existing maps while json parsing.
Review URL: https://chromiumcodereview.appspot.com/11184006 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12747 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
72424b3987
commit
b61933ba10
@ -289,6 +289,8 @@ Handle<Object> JsonParser<seq_ascii>::ParseJsonValue() {
|
|||||||
// Parse a JSON object. Position must be right at '{'.
|
// Parse a JSON object. Position must be right at '{'.
|
||||||
template <bool seq_ascii>
|
template <bool seq_ascii>
|
||||||
Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() {
|
Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() {
|
||||||
|
int current_index = 0;
|
||||||
|
Handle<Object> prototype;
|
||||||
Handle<JSFunction> object_constructor(
|
Handle<JSFunction> object_constructor(
|
||||||
isolate()->native_context()->object_function());
|
isolate()->native_context()->object_function());
|
||||||
Handle<JSObject> json_object =
|
Handle<JSObject> json_object =
|
||||||
@ -309,15 +311,20 @@ Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() {
|
|||||||
if (key->AsArrayIndex(&index)) {
|
if (key->AsArrayIndex(&index)) {
|
||||||
JSObject::SetOwnElement(json_object, index, value, kNonStrictMode);
|
JSObject::SetOwnElement(json_object, index, value, kNonStrictMode);
|
||||||
} else if (key->Equals(isolate()->heap()->Proto_symbol())) {
|
} else if (key->Equals(isolate()->heap()->Proto_symbol())) {
|
||||||
SetPrototype(json_object, value);
|
prototype = value;
|
||||||
} else {
|
} else {
|
||||||
JSObject::SetLocalPropertyIgnoreAttributes(
|
if (JSObject::TryTransitionToField(json_object, key)) {
|
||||||
json_object, key, value, NONE);
|
json_object->FastPropertyAtPut(current_index++, *value);
|
||||||
|
} else {
|
||||||
|
JSObject::SetLocalPropertyIgnoreAttributes(
|
||||||
|
json_object, key, value, NONE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} while (MatchSkipWhiteSpace(','));
|
} while (MatchSkipWhiteSpace(','));
|
||||||
if (c0_ != '}') {
|
if (c0_ != '}') {
|
||||||
return ReportUnexpectedCharacter();
|
return ReportUnexpectedCharacter();
|
||||||
}
|
}
|
||||||
|
if (!prototype.is_null()) SetPrototype(json_object, prototype);
|
||||||
}
|
}
|
||||||
AdvanceSkipWhitespace();
|
AdvanceSkipWhitespace();
|
||||||
return json_object;
|
return json_object;
|
||||||
|
@ -1414,6 +1414,36 @@ MaybeObject* JSObject::ResetElements() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MaybeObject* JSObject::AddFastPropertyUsingMap(Map* map) {
|
||||||
|
ASSERT(this->map()->NumberOfOwnDescriptors() + 1 ==
|
||||||
|
map->NumberOfOwnDescriptors());
|
||||||
|
if (this->map()->unused_property_fields() == 0) {
|
||||||
|
int new_size = properties()->length() + map->unused_property_fields() + 1;
|
||||||
|
FixedArray* new_properties;
|
||||||
|
MaybeObject* maybe_properties = properties()->CopySize(new_size);
|
||||||
|
if (!maybe_properties->To(&new_properties)) return maybe_properties;
|
||||||
|
set_properties(new_properties);
|
||||||
|
}
|
||||||
|
set_map(map);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool JSObject::TryTransitionToField(Handle<JSObject> object,
|
||||||
|
Handle<String> key) {
|
||||||
|
if (!object->map()->HasTransitionArray()) return false;
|
||||||
|
Handle<TransitionArray> transitions(object->map()->transitions());
|
||||||
|
int transition = transitions->Search(*key);
|
||||||
|
if (transition == TransitionArray::kNotFound) return false;
|
||||||
|
PropertyDetails target_details = transitions->GetTargetDetails(transition);
|
||||||
|
if (target_details.type() != FIELD) return false;
|
||||||
|
if (target_details.attributes() != NONE) return false;
|
||||||
|
Handle<Map> target(transitions->GetTarget(transition));
|
||||||
|
JSObject::AddFastPropertyUsingMap(object, target);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ACCESSORS(Oddball, to_string, String, kToStringOffset)
|
ACCESSORS(Oddball, to_string, String, kToStringOffset)
|
||||||
ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
|
ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
|
||||||
|
|
||||||
|
@ -2794,6 +2794,14 @@ MUST_USE_RESULT Handle<Object> JSProxy::CallTrap(const char* name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void JSObject::AddFastPropertyUsingMap(Handle<JSObject> object,
|
||||||
|
Handle<Map> map) {
|
||||||
|
CALL_HEAP_FUNCTION_VOID(
|
||||||
|
object->GetIsolate(),
|
||||||
|
object->AddFastPropertyUsingMap(*map));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
MaybeObject* JSObject::SetPropertyForResult(LookupResult* result,
|
MaybeObject* JSObject::SetPropertyForResult(LookupResult* result,
|
||||||
String* name_raw,
|
String* name_raw,
|
||||||
Object* value_raw,
|
Object* value_raw,
|
||||||
|
@ -1621,6 +1621,16 @@ class JSObject: public JSReceiver {
|
|||||||
Handle<Object> value,
|
Handle<Object> value,
|
||||||
PropertyAttributes attributes);
|
PropertyAttributes attributes);
|
||||||
|
|
||||||
|
// Try to follow an existing transition to a field with attributes NONE. The
|
||||||
|
// return value indicates whether the transition was successful.
|
||||||
|
static inline bool TryTransitionToField(Handle<JSObject> object,
|
||||||
|
Handle<String> key);
|
||||||
|
|
||||||
|
// Extend the receiver with a single fast property appeared first in the
|
||||||
|
// passed map. This also extends the property backing store if necessary.
|
||||||
|
static void AddFastPropertyUsingMap(Handle<JSObject> object, Handle<Map> map);
|
||||||
|
inline MUST_USE_RESULT MaybeObject* AddFastPropertyUsingMap(Map* map);
|
||||||
|
|
||||||
// Can cause GC.
|
// Can cause GC.
|
||||||
MUST_USE_RESULT MaybeObject* SetLocalPropertyIgnoreAttributes(
|
MUST_USE_RESULT MaybeObject* SetLocalPropertyIgnoreAttributes(
|
||||||
String* key,
|
String* key,
|
||||||
|
Loading…
Reference in New Issue
Block a user