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:
verwaest@chromium.org 2012-10-17 14:09:42 +00:00
parent 72424b3987
commit b61933ba10
4 changed files with 58 additions and 3 deletions

View File

@ -289,6 +289,8 @@ Handle<Object> JsonParser<seq_ascii>::ParseJsonValue() {
// Parse a JSON object. Position must be right at '{'.
template <bool seq_ascii>
Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() {
int current_index = 0;
Handle<Object> prototype;
Handle<JSFunction> object_constructor(
isolate()->native_context()->object_function());
Handle<JSObject> json_object =
@ -309,15 +311,20 @@ Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() {
if (key->AsArrayIndex(&index)) {
JSObject::SetOwnElement(json_object, index, value, kNonStrictMode);
} else if (key->Equals(isolate()->heap()->Proto_symbol())) {
SetPrototype(json_object, value);
prototype = value;
} else {
JSObject::SetLocalPropertyIgnoreAttributes(
json_object, key, value, NONE);
if (JSObject::TryTransitionToField(json_object, key)) {
json_object->FastPropertyAtPut(current_index++, *value);
} else {
JSObject::SetLocalPropertyIgnoreAttributes(
json_object, key, value, NONE);
}
}
} while (MatchSkipWhiteSpace(','));
if (c0_ != '}') {
return ReportUnexpectedCharacter();
}
if (!prototype.is_null()) SetPrototype(json_object, prototype);
}
AdvanceSkipWhitespace();
return json_object;

View File

@ -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_number, Object, kToNumberOffset)

View File

@ -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,
String* name_raw,
Object* value_raw,

View File

@ -1621,6 +1621,16 @@ class JSObject: public JSReceiver {
Handle<Object> value,
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.
MUST_USE_RESULT MaybeObject* SetLocalPropertyIgnoreAttributes(
String* key,