Revert r19430, r19459:

"Reland "Allow ICs to be generated for own global proxy.""

Causing ClusterFuzz crash (issue 343928)

TBR=verwaest@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19540 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 63f1970c
...@@ -1307,6 +1307,21 @@ void StoreStubCompiler::GenerateStoreViaSetter( ...@@ -1307,6 +1307,21 @@ void StoreStubCompiler::GenerateStoreViaSetter(
Handle<Code> StoreStubCompiler::CompileStoreInterceptor( Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
Handle<JSObject> object, Handle<JSObject> object,
Handle<Name> name) { Handle<Name> name) {
Label miss;
// Check that the map of the object hasn't changed.
__ CheckMap(receiver(), scratch1(), Handle<Map>(object->map()), &miss,
DO_SMI_CHECK);
// Perform global security token check if needed.
if (object->IsJSGlobalProxy()) {
__ CheckAccessGlobalProxy(receiver(), scratch1(), &miss);
}
// Stub is never generated for non-global objects that require access
// checks.
ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
__ Push(receiver(), this->name(), value()); __ Push(receiver(), this->name(), value());
// Do tail-call to the runtime system. // Do tail-call to the runtime system.
...@@ -1314,6 +1329,10 @@ Handle<Code> StoreStubCompiler::CompileStoreInterceptor( ...@@ -1314,6 +1329,10 @@ Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate());
__ TailCallExternalReference(store_ic_property, 3, 1); __ TailCallExternalReference(store_ic_property, 3, 1);
// Handle store cache miss.
__ bind(&miss);
TailCallBuiltin(masm(), MissBuiltin(kind()));
// Return the generated code. // Return the generated code.
return GetCode(kind(), Code::FAST, name); return GetCode(kind(), Code::FAST, name);
} }
......
...@@ -1051,16 +1051,13 @@ HValue* CodeStubGraphBuilder<StoreGlobalStub>::BuildCodeInitializedStub() { ...@@ -1051,16 +1051,13 @@ HValue* CodeStubGraphBuilder<StoreGlobalStub>::BuildCodeInitializedStub() {
Handle<PropertyCell> placeholder_cell = Handle<PropertyCell> placeholder_cell =
isolate()->factory()->NewPropertyCell(placeholer_value); isolate()->factory()->NewPropertyCell(placeholer_value);
HParameter* receiver = GetParameter(0);
HParameter* value = GetParameter(2); HParameter* value = GetParameter(2);
if (stub->check_global()) { // Check that the map of the global has not changed: use a placeholder map
// Check that the map of the global has not changed: use a placeholder map // that will be replaced later with the global object's map.
// that will be replaced later with the global object's map. Handle<Map> placeholder_map = isolate()->factory()->meta_map();
Handle<Map> placeholder_map = isolate()->factory()->meta_map(); Add<HCheckMaps>(receiver, placeholder_map, top_info());
HValue* global = Add<HConstant>(
StoreGlobalStub::global_placeholder(isolate()));
Add<HCheckMaps>(global, placeholder_map, top_info());
}
HValue* cell = Add<HConstant>(placeholder_cell); HValue* cell = Add<HConstant>(placeholder_cell);
HObjectAccess access(HObjectAccess::ForCellPayload(isolate())); HObjectAccess access(HObjectAccess::ForCellPayload(isolate()));
......
...@@ -963,27 +963,19 @@ class LoadFieldStub: public HandlerStub { ...@@ -963,27 +963,19 @@ class LoadFieldStub: public HandlerStub {
class StoreGlobalStub : public HandlerStub { class StoreGlobalStub : public HandlerStub {
public: public:
explicit StoreGlobalStub(bool is_constant, bool check_global) { explicit StoreGlobalStub(bool is_constant) {
bit_field_ = IsConstantBits::encode(is_constant) | bit_field_ = IsConstantBits::encode(is_constant);
CheckGlobalBits::encode(check_global);
}
static Handle<HeapObject> global_placeholder(Isolate* isolate) {
return isolate->factory()->uninitialized_value();
} }
Handle<Code> GetCodeCopyFromTemplate(Isolate* isolate, Handle<Code> GetCodeCopyFromTemplate(Isolate* isolate,
GlobalObject* global, Map* receiver_map,
PropertyCell* cell) { PropertyCell* cell) {
Handle<Code> code = CodeStub::GetCodeCopyFromTemplate(isolate); Handle<Code> code = CodeStub::GetCodeCopyFromTemplate(isolate);
if (check_global()) { // Replace the placeholder cell and global object map with the actual global
// Replace the placeholder cell and global object map with the actual // cell and receiver map.
// global cell and receiver map.
code->ReplaceNthObject(1, global_placeholder(isolate)->map(), global);
code->ReplaceNthObject(1, isolate->heap()->meta_map(), global->map());
}
Map* cell_map = isolate->heap()->global_property_cell_map(); Map* cell_map = isolate->heap()->global_property_cell_map();
code->ReplaceNthObject(1, cell_map, cell); code->ReplaceNthObject(1, cell_map, cell);
code->ReplaceNthObject(1, isolate->heap()->meta_map(), receiver_map);
return code; return code;
} }
...@@ -995,12 +987,9 @@ class StoreGlobalStub : public HandlerStub { ...@@ -995,12 +987,9 @@ class StoreGlobalStub : public HandlerStub {
Isolate* isolate, Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor); CodeStubInterfaceDescriptor* descriptor);
bool is_constant() const { bool is_constant() {
return IsConstantBits::decode(bit_field_); return IsConstantBits::decode(bit_field_);
} }
bool check_global() const {
return CheckGlobalBits::decode(bit_field_);
}
void set_is_constant(bool value) { void set_is_constant(bool value) {
bit_field_ = IsConstantBits::update(bit_field_, value); bit_field_ = IsConstantBits::update(bit_field_, value);
} }
...@@ -1017,7 +1006,6 @@ class StoreGlobalStub : public HandlerStub { ...@@ -1017,7 +1006,6 @@ class StoreGlobalStub : public HandlerStub {
class IsConstantBits: public BitField<bool, 0, 1> {}; class IsConstantBits: public BitField<bool, 0, 1> {};
class RepresentationBits: public BitField<Representation::Kind, 1, 8> {}; class RepresentationBits: public BitField<Representation::Kind, 1, 8> {};
class CheckGlobalBits: public BitField<bool, 9, 1> {};
DISALLOW_COPY_AND_ASSIGN(StoreGlobalStub); DISALLOW_COPY_AND_ASSIGN(StoreGlobalStub);
}; };
......
...@@ -1072,7 +1072,7 @@ MaybeObject* KeyedLoadIC::Load(Handle<Object> object, Handle<Object> key) { ...@@ -1072,7 +1072,7 @@ MaybeObject* KeyedLoadIC::Load(Handle<Object> object, Handle<Object> key) {
maybe_object = LoadIC::Load(object, Handle<String>::cast(key)); maybe_object = LoadIC::Load(object, Handle<String>::cast(key));
if (maybe_object->IsFailure()) return maybe_object; if (maybe_object->IsFailure()) return maybe_object;
} else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) { } else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) {
ASSERT(!object->IsAccessCheckNeeded()); ASSERT(!object->IsJSGlobalProxy());
if (object->IsString() && key->IsNumber()) { if (object->IsString() && key->IsNumber()) {
if (state() == UNINITIALIZED) stub = string_stub(); if (state() == UNINITIALIZED) stub = string_stub();
} else if (object->IsJSObject()) { } else if (object->IsJSObject()) {
...@@ -1111,17 +1111,21 @@ static bool LookupForWrite(Handle<JSObject> receiver, ...@@ -1111,17 +1111,21 @@ static bool LookupForWrite(Handle<JSObject> receiver,
Handle<JSObject> holder = receiver; Handle<JSObject> holder = receiver;
receiver->Lookup(*name, lookup); receiver->Lookup(*name, lookup);
if (lookup->IsFound()) { if (lookup->IsFound()) {
if (lookup->IsInterceptor() && !HasInterceptorSetter(lookup->holder())) { if (lookup->IsReadOnly() || !lookup->IsCacheable()) return false;
receiver->LocalLookupRealNamedProperty(*name, lookup);
if (!lookup->IsFound()) return false; if (lookup->holder() == *receiver) {
if (lookup->IsInterceptor() && !HasInterceptorSetter(*receiver)) {
receiver->LocalLookupRealNamedProperty(*name, lookup);
return lookup->IsFound() &&
!lookup->IsReadOnly() &&
lookup->CanHoldValue(value) &&
lookup->IsCacheable();
}
return lookup->CanHoldValue(value);
} }
if (lookup->IsReadOnly() || !lookup->IsCacheable()) return false;
if (lookup->holder() == *receiver) return lookup->CanHoldValue(value);
if (lookup->IsPropertyCallbacks()) return true; if (lookup->IsPropertyCallbacks()) return true;
// JSGlobalProxy either stores on the global object in the prototype, or // JSGlobalProxy always goes via the runtime, so it's safe to cache.
// goes into the runtime if access checks are needed, so this is always
// safe.
if (receiver->IsJSGlobalProxy()) return true; if (receiver->IsJSGlobalProxy()) return true;
// Currently normal holders in the prototype chain are not supported. They // Currently normal holders in the prototype chain are not supported. They
// would require a runtime positive lookup and verification that the details // would require a runtime positive lookup and verification that the details
...@@ -1307,7 +1311,7 @@ Handle<Code> StoreIC::CompileHandler(LookupResult* lookup, ...@@ -1307,7 +1311,7 @@ Handle<Code> StoreIC::CompileHandler(LookupResult* lookup,
Handle<String> name, Handle<String> name,
Handle<Object> value, Handle<Object> value,
InlineCacheHolderFlag cache_holder) { InlineCacheHolderFlag cache_holder) {
if (object->IsAccessCheckNeeded()) return slow_stub(); if (object->IsJSGlobalProxy()) return slow_stub();
ASSERT(cache_holder == OWN_MAP); ASSERT(cache_holder == OWN_MAP);
// This is currently guaranteed by checks in StoreIC::Store. // This is currently guaranteed by checks in StoreIC::Store.
Handle<JSObject> receiver = Handle<JSObject>::cast(object); Handle<JSObject> receiver = Handle<JSObject>::cast(object);
...@@ -1331,19 +1335,17 @@ Handle<Code> StoreIC::CompileHandler(LookupResult* lookup, ...@@ -1331,19 +1335,17 @@ Handle<Code> StoreIC::CompileHandler(LookupResult* lookup,
} }
case NORMAL: case NORMAL:
if (kind() == Code::KEYED_STORE_IC) break; if (kind() == Code::KEYED_STORE_IC) break;
if (receiver->IsJSGlobalProxy() || receiver->IsGlobalObject()) { if (receiver->IsGlobalObject()) {
// The stub generated for the global object picks the value directly // The stub generated for the global object picks the value directly
// from the property cell. So the property must be directly on the // from the property cell. So the property must be directly on the
// global object. // global object.
Handle<GlobalObject> global = receiver->IsJSGlobalProxy() Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
? handle(GlobalObject::cast(receiver->GetPrototype()))
: Handle<GlobalObject>::cast(receiver);
Handle<PropertyCell> cell(global->GetPropertyCell(lookup), isolate()); Handle<PropertyCell> cell(global->GetPropertyCell(lookup), isolate());
Handle<HeapType> union_type = PropertyCell::UpdatedType(cell, value); Handle<HeapType> union_type = PropertyCell::UpdatedType(cell, value);
StoreGlobalStub stub( StoreGlobalStub stub(union_type->IsConstant());
union_type->IsConstant(), receiver->IsJSGlobalProxy());
Handle<Code> code = stub.GetCodeCopyFromTemplate( Handle<Code> code = stub.GetCodeCopyFromTemplate(
isolate(), *global, *cell); isolate(), receiver->map(), *cell);
// TODO(verwaest): Move caching of these NORMAL stubs outside as well. // TODO(verwaest): Move caching of these NORMAL stubs outside as well.
HeapObject::UpdateMapCodeCache(receiver, name, code); HeapObject::UpdateMapCodeCache(receiver, name, code);
return code; return code;
...@@ -1384,7 +1386,7 @@ Handle<Code> StoreIC::CompileHandler(LookupResult* lookup, ...@@ -1384,7 +1386,7 @@ Handle<Code> StoreIC::CompileHandler(LookupResult* lookup,
} }
case INTERCEPTOR: case INTERCEPTOR:
if (kind() == Code::KEYED_STORE_IC) break; if (kind() == Code::KEYED_STORE_IC) break;
ASSERT(HasInterceptorSetter(*holder)); ASSERT(HasInterceptorSetter(*receiver));
return compiler.CompileStoreInterceptor(receiver, name); return compiler.CompileStoreInterceptor(receiver, name);
case CONSTANT: case CONSTANT:
break; break;
...@@ -1680,7 +1682,7 @@ MaybeObject* KeyedStoreIC::Store(Handle<Object> object, ...@@ -1680,7 +1682,7 @@ MaybeObject* KeyedStoreIC::Store(Handle<Object> object,
} }
if (use_ic) { if (use_ic) {
ASSERT(!object->IsAccessCheckNeeded()); ASSERT(!object->IsJSGlobalProxy());
if (object->IsJSObject()) { if (object->IsJSObject()) {
Handle<JSObject> receiver = Handle<JSObject>::cast(object); Handle<JSObject> receiver = Handle<JSObject>::cast(object);
......
...@@ -778,7 +778,7 @@ static MayAccessDecision MayAccessPreCheck(Isolate* isolate, ...@@ -778,7 +778,7 @@ static MayAccessDecision MayAccessPreCheck(Isolate* isolate,
bool Isolate::MayNamedAccess(JSObject* receiver, Object* key, bool Isolate::MayNamedAccess(JSObject* receiver, Object* key,
v8::AccessType type) { v8::AccessType type) {
ASSERT(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded()); ASSERT(receiver->IsAccessCheckNeeded());
// The callers of this method are not expecting a GC. // The callers of this method are not expecting a GC.
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
...@@ -829,7 +829,7 @@ bool Isolate::MayNamedAccess(JSObject* receiver, Object* key, ...@@ -829,7 +829,7 @@ bool Isolate::MayNamedAccess(JSObject* receiver, Object* key,
bool Isolate::MayIndexedAccess(JSObject* receiver, bool Isolate::MayIndexedAccess(JSObject* receiver,
uint32_t index, uint32_t index,
v8::AccessType type) { v8::AccessType type) {
ASSERT(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded()); ASSERT(receiver->IsAccessCheckNeeded());
// Check for compatibility between the security tokens in the // Check for compatibility between the security tokens in the
// current lexical context and the accessed object. // current lexical context and the accessed object.
ASSERT(context()); ASSERT(context());
......
...@@ -1293,6 +1293,21 @@ void StoreStubCompiler::GenerateStoreViaSetter( ...@@ -1293,6 +1293,21 @@ void StoreStubCompiler::GenerateStoreViaSetter(
Handle<Code> StoreStubCompiler::CompileStoreInterceptor( Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
Handle<JSObject> object, Handle<JSObject> object,
Handle<Name> name) { Handle<Name> name) {
Label miss;
// Check that the map of the object hasn't changed.
__ CheckMap(receiver(), scratch1(), Handle<Map>(object->map()), &miss,
DO_SMI_CHECK);
// Perform global security token check if needed.
if (object->IsJSGlobalProxy()) {
__ CheckAccessGlobalProxy(receiver(), scratch1(), &miss);
}
// Stub is never generated for non-global objects that require access
// checks.
ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
__ Push(receiver(), this->name(), value()); __ Push(receiver(), this->name(), value());
// Do tail-call to the runtime system. // Do tail-call to the runtime system.
...@@ -1300,6 +1315,10 @@ Handle<Code> StoreStubCompiler::CompileStoreInterceptor( ...@@ -1300,6 +1315,10 @@ Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate());
__ TailCallExternalReference(store_ic_property, 3, 1); __ TailCallExternalReference(store_ic_property, 3, 1);
// Handle store cache miss.
__ bind(&miss);
TailCallBuiltin(masm(), MissBuiltin(kind()));
// Return the generated code. // Return the generated code.
return GetCode(kind(), Code::FAST, name); return GetCode(kind(), Code::FAST, name);
} }
......
...@@ -927,8 +927,7 @@ bool Object::IsJSGlobalProxy() { ...@@ -927,8 +927,7 @@ bool Object::IsJSGlobalProxy() {
bool result = IsHeapObject() && bool result = IsHeapObject() &&
(HeapObject::cast(this)->map()->instance_type() == (HeapObject::cast(this)->map()->instance_type() ==
JS_GLOBAL_PROXY_TYPE); JS_GLOBAL_PROXY_TYPE);
ASSERT(!result || ASSERT(!result || IsAccessCheckNeeded());
HeapObject::cast(this)->map()->is_access_check_needed());
return result; return result;
} }
...@@ -953,14 +952,8 @@ bool Object::IsUndetectableObject() { ...@@ -953,14 +952,8 @@ bool Object::IsUndetectableObject() {
bool Object::IsAccessCheckNeeded() { bool Object::IsAccessCheckNeeded() {
if (!IsHeapObject()) return false; return IsHeapObject()
if (IsJSGlobalProxy()) { && HeapObject::cast(this)->map()->is_access_check_needed();
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();
} }
......
...@@ -2361,6 +2361,10 @@ class JSObject: public JSReceiver { ...@@ -2361,6 +2361,10 @@ class JSObject: public JSReceiver {
// been modified since it was created. May give false positives. // been modified since it was created. May give false positives.
bool IsDirty(); bool IsDirty();
// If the receiver is a JSGlobalProxy this method will return its prototype,
// otherwise the result is the receiver itself.
inline Object* BypassGlobalProxy();
// Accessors for hidden properties object. // Accessors for hidden properties object.
// //
// Hidden properties are not local properties of the object itself. // Hidden properties are not local properties of the object itself.
......
...@@ -14735,7 +14735,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IsAccessAllowedForObserver) { ...@@ -14735,7 +14735,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IsAccessAllowedForObserver) {
ASSERT(args.length() == 3); ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0); CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 1); CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 1);
ASSERT(object->map()->is_access_check_needed()); ASSERT(object->IsAccessCheckNeeded());
Handle<Object> key = args.at<Object>(2); Handle<Object> key = args.at<Object>(2);
SaveContext save(isolate); SaveContext save(isolate);
isolate->set_context(observer->context()); isolate->set_context(observer->context());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment