Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(913)

Unified Diff: src/runtime.cc

Issue 348313002: Introduce a PrototypeIterator template and use it all over the place (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: rebase Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/prototype-iterator.h ('k') | src/string-stream.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index 3cb6fe20a20b752b42e042f33585459df27ef8aa..b1ade5e0ce491412912a5d445ea425021cf67281 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -34,6 +34,7 @@
#include "src/misc-intrinsics.h"
#include "src/parser.h"
#include "src/platform.h"
+#include "src/prototype-iterator.h"
#include "src/runtime.h"
#include "src/runtime-profiler.h"
#include "src/scopeinfo.h"
@@ -1809,31 +1810,30 @@ RUNTIME_FUNCTION(Runtime_GetPrototype) {
CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
// We don't expect access checks to be needed on JSProxy objects.
ASSERT(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
+ PrototypeIterator<STORE_AS_HANDLE, TYPE_BASED_WALK, END_AT_NON_HIDDEN> iter(
+ isolate, obj);
do {
- if (obj->IsAccessCheckNeeded() &&
- !isolate->MayNamedAccess(Handle<JSObject>::cast(obj),
+ if (iter.GetCurrent()->IsAccessCheckNeeded() &&
+ !isolate->MayNamedAccess(Handle<JSObject>::cast(iter.GetCurrent()),
isolate->factory()->proto_string(),
v8::ACCESS_GET)) {
- isolate->ReportFailedAccessCheck(Handle<JSObject>::cast(obj),
- v8::ACCESS_GET);
+ isolate->ReportFailedAccessCheck(
+ Handle<JSObject>::cast(iter.GetCurrent()), v8::ACCESS_GET);
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return isolate->heap()->undefined_value();
}
- obj = Object::GetPrototype(isolate, obj);
- } while (obj->IsJSObject() &&
- JSObject::cast(*obj)->map()->is_hidden_prototype());
- return *obj;
+ iter.Advance();
+ } while (!iter.IsAtEnd());
+ return *iter.GetCurrent();
}
static inline Handle<Object> GetPrototypeSkipHiddenPrototypes(
Isolate* isolate, Handle<Object> receiver) {
- Handle<Object> current = Object::GetPrototype(isolate, receiver);
- while (current->IsJSObject() &&
- JSObject::cast(*current)->map()->is_hidden_prototype()) {
- current = Object::GetPrototype(isolate, current);
- }
- return current;
+ PrototypeIterator<STORE_AS_HANDLE, TYPE_BASED_WALK, END_AT_NON_HIDDEN> iter(
+ isolate, receiver);
+ while (!iter.IsAtEnd()) iter.Advance();
+ return iter.GetCurrent();
}
@@ -1878,12 +1878,11 @@ RUNTIME_FUNCTION(Runtime_IsInPrototypeChain) {
// See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8).
CONVERT_ARG_HANDLE_CHECKED(Object, O, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, V, 1);
- while (true) {
- Handle<Object> prototype = Object::GetPrototype(isolate, V);
- if (prototype->IsNull()) return isolate->heap()->false_value();
- if (*O == *prototype) return isolate->heap()->true_value();
- V = prototype;
- }
+ PrototypeIterator<STORE_AS_HANDLE, TYPE_BASED_WALK, END_AT_GIVEN_OBJECT> iter(
+ isolate, V, O);
+ while (!iter.IsAtEnd()) iter.Advance();
+ if (iter.GetCurrent()->IsNull()) return isolate->heap()->false_value();
+ return isolate->heap()->true_value();
}
@@ -2006,7 +2005,7 @@ RUNTIME_FUNCTION(Runtime_IsExtensible) {
ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSObject, obj, 0);
if (obj->IsJSGlobalProxy()) {
- Object* proto = obj->GetPrototype();
+ Object* proto = SAFE_GET_PROTOTYPE_FAST(obj);
if (proto->IsNull()) return isolate->heap()->false_value();
ASSERT(proto->IsJSGlobalObject());
obj = JSObject::cast(proto);
@@ -4833,7 +4832,7 @@ MaybeHandle<Object> Runtime::GetElementOrCharAt(Isolate* isolate,
Handle<Object> result;
if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
- Handle<Object> proto(object->GetPrototype(isolate), isolate);
+ Handle<Object> proto(SAFE_GET_PROTOTYPE(isolate, *object), isolate);
return Object::GetElement(isolate, proto, index);
} else {
return Object::GetElement(isolate, object, index);
@@ -5097,7 +5096,8 @@ RUNTIME_FUNCTION(Runtime_DefineOrRedefineDataProperty) {
if (js_object->IsJSGlobalProxy()) {
// Since the result is a property, the prototype will exist so
// we don't have to check for null.
- js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype()));
+ js_object =
+ Handle<JSObject>(JSObject::cast(SAFE_GET_PROTOTYPE_FAST(*js_object)));
}
if (attr != lookup.GetAttributes() ||
@@ -5572,7 +5572,7 @@ static Object* HasOwnPropertyImplementation(Isolate* isolate,
// Handle hidden prototypes. If there's a hidden prototype above this thing
// then we have to check it for properties, because they are supposed to
// look like they are on this object.
- Handle<Object> proto(object->GetPrototype(), isolate);
+ Handle<Object> proto(SAFE_GET_PROTOTYPE_FAST(*object), isolate);
if (proto->IsJSObject() &&
Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) {
return HasOwnPropertyImplementation(isolate,
@@ -5714,12 +5714,10 @@ RUNTIME_FUNCTION(Runtime_GetPropertyNamesFast) {
// prototype object is hidden it is to be viewed as part of the the object it
// is prototype for.
static int OwnPrototypeChainLength(JSObject* obj) {
- int count = 1;
- Object* proto = obj->GetPrototype();
- while (proto->IsJSObject() &&
- JSObject::cast(proto)->map()->is_hidden_prototype()) {
- count++;
- proto = JSObject::cast(proto)->GetPrototype();
+ int count = 0;
+ for (PrototypeIterator<STORE_AS_POINTER, MAP_BASED_WALK, END_AT_NON_HIDDEN>
+ iter(obj); !iter.IsAtEnd(); iter.Advance()) {
+ ++count;
}
return count;
}
@@ -5749,7 +5747,7 @@ RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) {
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
return *isolate->factory()->NewJSArray(0);
}
- obj = Handle<JSObject>(JSObject::cast(obj->GetPrototype()));
+ obj = Handle<JSObject>(JSObject::cast(SAFE_GET_PROTOTYPE_FAST(*obj)));
}
// Find the number of objects making up this.
@@ -5773,7 +5771,8 @@ RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) {
own_property_count[i] = n;
total_property_count += n;
if (i < length - 1) {
- jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
+ jsproto =
+ Handle<JSObject>(JSObject::cast(SAFE_GET_PROTOTYPE_FAST(*jsproto)));
}
}
@@ -5814,7 +5813,8 @@ RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) {
hidden_strings++;
}
if (i < length - 1) {
- jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
+ jsproto =
+ Handle<JSObject>(JSObject::cast(SAFE_GET_PROTOTYPE_FAST(*jsproto)));
}
}
@@ -5925,7 +5925,7 @@ RUNTIME_FUNCTION(Runtime_OwnKeys) {
return *isolate->factory()->NewJSArray(0);
}
- Handle<Object> proto(object->GetPrototype(), isolate);
+ Handle<Object> proto(SAFE_GET_PROTOTYPE_FAST(*object), isolate);
// If proxy is detached we simply return an empty array.
if (proto->IsNull()) return *isolate->factory()->NewJSArray(0);
object = Handle<JSObject>::cast(proto);
@@ -10212,7 +10212,7 @@ static void CollectElementIndices(Handle<JSObject> object,
}
}
- Handle<Object> prototype(object->GetPrototype(), isolate);
+ Handle<Object> prototype(SAFE_GET_PROTOTYPE_FAST(*object), isolate);
if (prototype->IsJSObject()) {
// The prototype will usually have no inherited element indices,
// but we have to check.
@@ -10645,15 +10645,15 @@ RUNTIME_FUNCTION(Runtime_GetArrayKeys) {
CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]);
if (array->elements()->IsDictionary()) {
Handle<FixedArray> keys = isolate->factory()->empty_fixed_array();
- for (Handle<Object> p = array;
- !p->IsNull();
- p = Handle<Object>(p->GetPrototype(isolate), isolate)) {
- if (p->IsJSProxy() || JSObject::cast(*p)->HasIndexedInterceptor()) {
+ for (PrototypeIterator<STORE_AS_HANDLE, TYPE_BASED_WALK, END_AT_NULL_VALUE>
+ iter(isolate, array); !iter.IsAtEnd(); iter.Advance()) {
+ if (iter.GetCurrent()->IsJSProxy() ||
+ JSObject::cast(*iter.GetCurrent())->HasIndexedInterceptor()) {
// Bail out if we find a proxy or interceptor, likely not worth
// collecting keys in that case.
return *isolate->factory()->NewNumberFromUint(length);
}
- Handle<JSObject> current = Handle<JSObject>::cast(p);
+ Handle<JSObject> current = Handle<JSObject>::cast(iter.GetCurrent());
Handle<FixedArray> current_keys =
isolate->factory()->NewFixedArray(current->NumberOfOwnElements(NONE));
current->GetOwnElementKeys(*current_keys, NONE);
@@ -10872,7 +10872,8 @@ RUNTIME_FUNCTION(Runtime_DebugGetPropertyDetails) {
return *isolate->factory()->NewJSArrayWithElements(details);
}
if (i < length - 1) {
- jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
+ jsproto =
+ Handle<JSObject>(JSObject::cast(SAFE_GET_PROTOTYPE_FAST(*jsproto)));
}
}
@@ -12820,7 +12821,8 @@ static MaybeHandle<Object> DebugEvaluate(Isolate* isolate,
// Skip the global proxy as it has no properties and always delegates to the
// real global object.
if (result->IsJSGlobalProxy()) {
- result = Handle<JSObject>(JSObject::cast(result->GetPrototype(isolate)));
+ result =
+ Handle<JSObject>(JSObject::cast(SAFE_GET_PROTOTYPE(isolate, *result)));
}
// Clear the oneshot breakpoints so that the debugger does not step further.
@@ -12996,17 +12998,13 @@ static int DebugReferencedBy(HeapIterator* iterator,
// Check instance filter if supplied. This is normally used to avoid
// references from mirror objects (see Runtime_IsInPrototypeChain).
if (!instance_filter->IsUndefined()) {
- Object* V = obj;
- while (true) {
- Object* prototype = V->GetPrototype(isolate);
- if (prototype->IsNull()) {
- break;
- }
- if (instance_filter == prototype) {
- obj = NULL; // Don't add this object.
+ for (PrototypeIterator<STORE_AS_POINTER, TYPE_BASED_WALK,
+ END_AT_NULL_VALUE> iter(isolate, obj);
+ !iter.IsAtEnd(); iter.Advance()) {
+ if (instance_filter == iter.GetCurrent()) {
+ obj = NULL;
break;
}
- V = prototype;
}
}
« no previous file with comments | « src/prototype-iterator.h ('k') | src/string-stream.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698