Reviewers: dcarney,
Message:
PTAL
Description:
Allow ICs to be generated for own global proxy.
Please review this at https://codereview.chromium.org/166233004/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+28, -13 lines):
src/ic.cc
src/isolate.cc
src/objects-inl.h
src/runtime.cc
Index: src/ic.cc
diff --git a/src/ic.cc b/src/ic.cc
index
44bc2f2e6b4a56fad8e89fab7e997e58615f8073..322b082f225abb3a5218a46232fdafee07024b92
100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -1069,7 +1069,7 @@ MaybeObject* KeyedLoadIC::Load(Handle<Object> object,
Handle<Object> key) {
maybe_object = LoadIC::Load(object, Handle<String>::cast(key));
if (maybe_object->IsFailure()) return maybe_object;
} else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) {
- ASSERT(!object->IsJSGlobalProxy());
+ ASSERT(!object->IsAccessCheckNeeded());
if (object->IsString() && key->IsNumber()) {
if (state() == UNINITIALIZED) stub = string_stub();
} else if (object->IsJSObject()) {
@@ -1122,7 +1122,9 @@ static bool LookupForWrite(Handle<JSObject> receiver,
}
if (lookup->IsPropertyCallbacks()) return true;
- // JSGlobalProxy always goes via the runtime, so it's safe to cache.
+ // JSGlobalProxy either stores on the global object in the prototype,
or
+ // goes into the runtime if access checks are needed, so this is always
+ // safe.
if (receiver->IsJSGlobalProxy()) return true;
// Currently normal holders in the prototype chain are not supported.
They
// would require a runtime positive lookup and verification that the
details
@@ -1309,7 +1311,7 @@ Handle<Code> StoreIC::CompileHandler(LookupResult*
lookup,
Handle<String> name,
Handle<Object> value,
InlineCacheHolderFlag cache_holder) {
- if (object->IsJSGlobalProxy()) return slow_stub();
+ if (object->IsAccessCheckNeeded()) return slow_stub();
ASSERT(cache_holder == OWN_MAP);
// This is currently guaranteed by checks in StoreIC::Store.
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
@@ -1337,17 +1339,23 @@ Handle<Code> StoreIC::CompileHandler(LookupResult*
lookup,
}
case NORMAL:
if (kind() == Code::KEYED_STORE_IC) break;
- if (receiver->IsGlobalObject()) {
+ if (receiver->IsJSGlobalProxy() || receiver->IsGlobalObject()) {
// The stub generated for the global object picks the value
directly
// from the property cell. So the property must be directly on the
// global object.
- Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
+ Handle<GlobalObject> global = receiver->IsJSGlobalProxy()
+ ? handle(GlobalObject::cast(receiver->GetPrototype()))
+ : Handle<GlobalObject>::cast(receiver);
Handle<PropertyCell> cell(global->GetPropertyCell(lookup),
isolate());
Handle<HeapType> union_type = PropertyCell::UpdatedType(cell,
value);
StoreGlobalStub stub(union_type->IsConstant());
+ // TODO(verwaest): Currently the StoreGlobalStub duplicates the
mapcheck
+ // if the receiver is the global object, which was already checked
by
+ // the IC and does not need to be rechecked by the handler. This
can be
+ // streamlined by removing the secondary mapcheck.
Handle<Code> code = stub.GetCodeCopyFromTemplate(
- isolate(), receiver->map(), *cell);
+ isolate(), global->map(), *cell);
// TODO(verwaest): Move caching of these NORMAL stubs outside as
well.
HeapObject::UpdateMapCodeCache(receiver, name, code);
return code;
@@ -1684,7 +1692,7 @@ MaybeObject* KeyedStoreIC::Store(Handle<Object>
object,
}
if (use_ic) {
- ASSERT(!object->IsJSGlobalProxy());
+ ASSERT(!object->IsAccessCheckNeeded());
if (object->IsJSObject()) {
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
Index: src/isolate.cc
diff --git a/src/isolate.cc b/src/isolate.cc
index
a008b6a3c1c402fb747773f4bfade3490a6231df..ca324603f79bdbbab5b62972c72ab84f948fb31d
100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -778,7 +778,7 @@ static MayAccessDecision MayAccessPreCheck(Isolate*
isolate,
bool Isolate::MayNamedAccess(JSObject* receiver, Object* key,
v8::AccessType type) {
- ASSERT(receiver->IsAccessCheckNeeded());
+ ASSERT(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded());
// The callers of this method are not expecting a GC.
DisallowHeapAllocation no_gc;
@@ -829,7 +829,7 @@ bool Isolate::MayNamedAccess(JSObject* receiver,
Object* key,
bool Isolate::MayIndexedAccess(JSObject* receiver,
uint32_t index,
v8::AccessType type) {
- ASSERT(receiver->IsAccessCheckNeeded());
+ ASSERT(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded());
// Check for compatibility between the security tokens in the
// current lexical context and the accessed object.
ASSERT(context());
Index: src/objects-inl.h
diff --git a/src/objects-inl.h b/src/objects-inl.h
index
97f00ade4da389da6f87be5f7f4fd2ea47fe983d..05df48fd16de3cc212967ec04ae8c3f11e2fe0bc
100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -927,7 +927,8 @@ bool Object::IsJSGlobalProxy() {
bool result = IsHeapObject() &&
(HeapObject::cast(this)->map()->instance_type() ==
JS_GLOBAL_PROXY_TYPE);
- ASSERT(!result || IsAccessCheckNeeded());
+ ASSERT(!result ||
+ HeapObject::cast(this)->map()->is_access_check_needed());
return result;
}
@@ -952,8 +953,14 @@ bool Object::IsUndetectableObject() {
bool Object::IsAccessCheckNeeded() {
- return IsHeapObject()
- && HeapObject::cast(this)->map()->is_access_check_needed();
+ if (!IsHeapObject()) return false;
+ if (IsJSGlobalProxy()) {
+ JSGlobalProxy* proxy = JSGlobalProxy::cast(this);
+ GlobalObject* global =
+ proxy->GetIsolate()->context()->global_object();
+ return proxy->IsDetachedFrom(global);
+ }
+ return HeapObject::cast(this)->map()->is_access_check_needed();
}
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index
3ab39abfcc7676d288c57bba9ff0d81672e6a51c..958675aa953004de08e40546e188191ccdd7bf41
100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -14649,7 +14649,7 @@ RUNTIME_FUNCTION(MaybeObject*,
Runtime_IsAccessAllowedForObserver) {
ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 1);
- ASSERT(object->IsAccessCheckNeeded());
+ ASSERT(object->map()->is_access_check_needed());
Handle<Object> key = args.at<Object>(2);
SaveContext save(isolate);
isolate->set_context(observer->context());
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.