Handlify JSObject::SetObserved

BUG=
R=mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/27070002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17224 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
rafaelw@chromium.org 2013-10-15 19:28:11 +00:00
parent 5b9f8f32e7
commit 2268defb84
3 changed files with 32 additions and 25 deletions

View File

@ -5581,37 +5581,34 @@ Handle<Object> JSObject::Freeze(Handle<JSObject> object) {
} }
MUST_USE_RESULT MaybeObject* JSObject::SetObserved(Isolate* isolate) { void JSObject::SetObserved(Handle<JSObject> object) {
if (map()->is_observed()) Isolate* isolate = object->GetIsolate();
return isolate->heap()->undefined_value();
Heap* heap = isolate->heap(); if (object->map()->is_observed())
return;
if (!HasExternalArrayElements()) { if (!object->HasExternalArrayElements()) {
// Go to dictionary mode, so that we don't skip map checks. // Go to dictionary mode, so that we don't skip map checks.
MaybeObject* maybe = NormalizeElements(); NormalizeElements(object);
if (maybe->IsFailure()) return maybe; ASSERT(!object->HasFastElements());
ASSERT(!HasFastElements());
} }
LookupResult result(isolate); LookupResult result(isolate);
map()->LookupTransition(this, heap->observed_symbol(), &result); object->map()->LookupTransition(*object,
isolate->heap()->observed_symbol(),
&result);
Map* new_map; Handle<Map> new_map;
if (result.IsTransition()) { if (result.IsTransition()) {
new_map = result.GetTransitionTarget(); new_map = handle(result.GetTransitionTarget());
ASSERT(new_map->is_observed()); ASSERT(new_map->is_observed());
} else if (map()->CanHaveMoreTransitions()) { } else if (object->map()->CanHaveMoreTransitions()) {
MaybeObject* maybe_new_map = map()->CopyForObserved(); new_map = Map::CopyForObserved(handle(object->map()));
if (!maybe_new_map->To(&new_map)) return maybe_new_map;
} else { } else {
MaybeObject* maybe_copy = map()->Copy(); new_map = Map::Copy(handle(object->map()));
if (!maybe_copy->To(&new_map)) return maybe_copy;
new_map->set_is_observed(true); new_map->set_is_observed(true);
} }
set_map(new_map); object->set_map(*new_map);
return heap->undefined_value();
} }
@ -6839,6 +6836,13 @@ MaybeObject* Map::CopyAsElementsKind(ElementsKind kind, TransitionFlag flag) {
} }
Handle<Map> Map::CopyForObserved(Handle<Map> map) {
CALL_HEAP_FUNCTION(map->GetIsolate(),
map->CopyForObserved(),
Map);
}
MaybeObject* Map::CopyForObserved() { MaybeObject* Map::CopyForObserved() {
ASSERT(!is_observed()); ASSERT(!is_observed());

View File

@ -2541,7 +2541,7 @@ class JSObject: public JSReceiver {
static Handle<Object> Freeze(Handle<JSObject> object); static Handle<Object> Freeze(Handle<JSObject> object);
// Called the first time an object is observed with ES7 Object.observe. // Called the first time an object is observed with ES7 Object.observe.
MUST_USE_RESULT MaybeObject* SetObserved(Isolate* isolate); static void SetObserved(Handle<JSObject> object);
// Copy object. // Copy object.
static Handle<JSObject> Copy(Handle<JSObject> object); static Handle<JSObject> Copy(Handle<JSObject> object);
@ -5977,6 +5977,8 @@ class Map: public HeapObject {
MUST_USE_RESULT MaybeObject* CopyAsElementsKind(ElementsKind kind, MUST_USE_RESULT MaybeObject* CopyAsElementsKind(ElementsKind kind,
TransitionFlag flag); TransitionFlag flag);
static Handle<Map> CopyForObserved(Handle<Map> map);
MUST_USE_RESULT MaybeObject* CopyForObserved(); MUST_USE_RESULT MaybeObject* CopyForObserved();
static Handle<Map> CopyNormalized(Handle<Map> map, static Handle<Map> CopyNormalized(Handle<Map> map,

View File

@ -14566,22 +14566,23 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IsObserved) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_SetIsObserved) { RUNTIME_FUNCTION(MaybeObject*, Runtime_SetIsObserved) {
SealHandleScope shs(isolate); HandleScope scope(isolate);
ASSERT(args.length() == 1); ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSReceiver, obj, 0); CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
if (obj->IsJSGlobalProxy()) { if (obj->IsJSGlobalProxy()) {
Object* proto = obj->GetPrototype(); Object* proto = obj->GetPrototype();
if (proto->IsNull()) return isolate->heap()->undefined_value(); if (proto->IsNull()) return isolate->heap()->undefined_value();
ASSERT(proto->IsJSGlobalObject()); ASSERT(proto->IsJSGlobalObject());
obj = JSReceiver::cast(proto); obj = handle(JSReceiver::cast(proto));
} }
if (obj->IsJSProxy()) if (obj->IsJSProxy())
return isolate->heap()->undefined_value(); return isolate->heap()->undefined_value();
ASSERT(!(obj->map()->is_observed() && obj->IsJSObject() && ASSERT(!(obj->map()->is_observed() && obj->IsJSObject() &&
JSObject::cast(obj)->HasFastElements())); Handle<JSObject>::cast(obj)->HasFastElements()));
ASSERT(obj->IsJSObject()); ASSERT(obj->IsJSObject());
return JSObject::cast(obj)->SetObserved(isolate); JSObject::SetObserved(Handle<JSObject>::cast(obj));
return isolate->heap()->undefined_value();
} }