Commit ba6a1a7c authored by Maya Lekova's avatar Maya Lekova Committed by V8 LUCI CQ

Revert "[ic] Fix handling of API properties with side effects"

This reverts commit 0ce36e7d.

Reason for revert: Speculative revert for a Chromium build breakage causing a blocked roll - https://bugs.chromium.org/p/v8/issues/detail?id=11761

Original change's description:
> [ic] Fix handling of API properties with side effects
>
> DebugEvaluate can evaluate expressions in side-effect-free mode, where
> any operation that would cause observable side effects throws an
> exception. Currently, when accessors are backed by callbacks, it's
> possible that ICs call those accessors directly, bypassing the
> side-effect checks. This CL introduces a bailouts to runtime in those
> cases.
>
> Fixed: chromium:1201781
> Also-By: ishell@chromium.org, pfaffe@chromium.org
> Change-Id: Ie53bfb2bff7b3420f2b27091e8df6723382cf53c
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2857634
> Commit-Queue: Philip Pfaffe <pfaffe@chromium.org>
> Reviewed-by: Igor Sheludko <ishell@chromium.org>
> Reviewed-by: Yang Guo <yangguo@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#74507}

Change-Id: Ifb5c24682af29572591d436ab92b0304058e99af
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2891650
Auto-Submit: Maya Lekova <mslekova@chromium.org>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/heads/master@{#74515}
parent aa6d6538
...@@ -8930,9 +8930,9 @@ void CodeStubAssembler::ForEachEnumerableOwnProperty( ...@@ -8930,9 +8930,9 @@ void CodeStubAssembler::ForEachEnumerableOwnProperty(
{ {
Label slow_load(this, Label::kDeferred); Label slow_load(this, Label::kDeferred);
var_value = CallGetterIfAccessor( var_value = CallGetterIfAccessor(var_value.value(), object,
var_value.value(), object, var_details.value(), context, object, var_details.value(), context,
next_key, &slow_load, kCallJSGetter); object, &slow_load, kCallJSGetter);
Goto(&callback); Goto(&callback);
BIND(&slow_load); BIND(&slow_load);
...@@ -9384,8 +9384,8 @@ template void CodeStubAssembler::LoadPropertyFromDictionary( ...@@ -9384,8 +9384,8 @@ template void CodeStubAssembler::LoadPropertyFromDictionary(
// result of the getter call. // result of the getter call.
TNode<Object> CodeStubAssembler::CallGetterIfAccessor( TNode<Object> CodeStubAssembler::CallGetterIfAccessor(
TNode<Object> value, TNode<HeapObject> holder, TNode<Uint32T> details, TNode<Object> value, TNode<HeapObject> holder, TNode<Uint32T> details,
TNode<Context> context, TNode<Object> receiver, TNode<Object> name, TNode<Context> context, TNode<Object> receiver, Label* if_bailout,
Label* if_bailout, GetOwnPropertyMode mode) { GetOwnPropertyMode mode) {
TVARIABLE(Object, var_value, value); TVARIABLE(Object, var_value, value);
Label done(this), if_accessor_info(this, Label::kDeferred); Label done(this), if_accessor_info(this, Label::kDeferred);
...@@ -9413,16 +9413,13 @@ TNode<Object> CodeStubAssembler::CallGetterIfAccessor( ...@@ -9413,16 +9413,13 @@ TNode<Object> CodeStubAssembler::CallGetterIfAccessor(
BIND(&if_callable); BIND(&if_callable);
{ {
// Call the accessor. No need to check side-effect mode here, since it // Call the accessor.
// will be checked later in DebugOnFunctionCall.
var_value = Call(context, getter, receiver); var_value = Call(context, getter, receiver);
Goto(&done); Goto(&done);
} }
BIND(&if_function_template_info); BIND(&if_function_template_info);
{ {
Label runtime(this, Label::kDeferred);
GotoIf(IsSideEffectFreeDebuggingActive(), &runtime);
TNode<HeapObject> cached_property_name = LoadObjectField<HeapObject>( TNode<HeapObject> cached_property_name = LoadObjectField<HeapObject>(
getter, FunctionTemplateInfo::kCachedPropertyNameOffset); getter, FunctionTemplateInfo::kCachedPropertyNameOffset);
GotoIfNot(IsTheHole(cached_property_name), if_bailout); GotoIfNot(IsTheHole(cached_property_name), if_bailout);
...@@ -9433,13 +9430,6 @@ TNode<Object> CodeStubAssembler::CallGetterIfAccessor( ...@@ -9433,13 +9430,6 @@ TNode<Object> CodeStubAssembler::CallGetterIfAccessor(
Builtins::kCallFunctionTemplate_CheckAccessAndCompatibleReceiver, Builtins::kCallFunctionTemplate_CheckAccessAndCompatibleReceiver,
creation_context, getter, IntPtrConstant(0), receiver); creation_context, getter, IntPtrConstant(0), receiver);
Goto(&done); Goto(&done);
BIND(&runtime);
{
var_value = CallRuntime(Runtime::kGetProperty, context, holder, name,
receiver);
Goto(&done);
}
} }
} else { } else {
Goto(&done); Goto(&done);
...@@ -9574,7 +9564,7 @@ void CodeStubAssembler::TryGetOwnProperty( ...@@ -9574,7 +9564,7 @@ void CodeStubAssembler::TryGetOwnProperty(
} }
TNode<Object> value = TNode<Object> value =
CallGetterIfAccessor(var_value->value(), object, var_details->value(), CallGetterIfAccessor(var_value->value(), object, var_details->value(),
context, receiver, unique_name, if_bailout, mode); context, receiver, if_bailout, mode);
*var_value = value; *var_value = value;
Goto(if_found_value); Goto(if_found_value);
} }
...@@ -14026,20 +14016,6 @@ TNode<BoolT> CodeStubAssembler::IsDebugActive() { ...@@ -14026,20 +14016,6 @@ TNode<BoolT> CodeStubAssembler::IsDebugActive() {
return Word32NotEqual(is_debug_active, Int32Constant(0)); return Word32NotEqual(is_debug_active, Int32Constant(0));
} }
TNode<BoolT> CodeStubAssembler::IsSideEffectFreeDebuggingActive() {
TNode<Uint8T> debug_execution_mode = Load<Uint8T>(ExternalConstant(
ExternalReference::debug_execution_mode_address(isolate())));
TNode<BoolT> is_active =
Word32Equal(debug_execution_mode,
Int32Constant(DebugInfo::ExecutionMode::kSideEffects));
#ifdef DEBUG
CSA_ASSERT(this, Word32Or(IsDebugActive(), Word32BinaryNot(is_active)));
#endif
return is_active;
}
TNode<BoolT> CodeStubAssembler::HasAsyncEventDelegate() { TNode<BoolT> CodeStubAssembler::HasAsyncEventDelegate() {
const TNode<RawPtrT> async_event_delegate = Load<RawPtrT>(ExternalConstant( const TNode<RawPtrT> async_event_delegate = Load<RawPtrT>(ExternalConstant(
ExternalReference::async_event_delegate_address(isolate()))); ExternalReference::async_event_delegate_address(isolate())));
......
...@@ -3481,7 +3481,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -3481,7 +3481,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
// Debug helpers // Debug helpers
TNode<BoolT> IsDebugActive(); TNode<BoolT> IsDebugActive();
TNode<BoolT> IsSideEffectFreeDebuggingActive();
// JSArrayBuffer helpers // JSArrayBuffer helpers
TNode<RawPtrT> LoadJSArrayBufferBackingStorePtr( TNode<RawPtrT> LoadJSArrayBufferBackingStorePtr(
...@@ -3756,10 +3755,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -3756,10 +3755,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
const ForEachKeyValueFunction& body, const ForEachKeyValueFunction& body,
Label* bailout); Label* bailout);
TNode<Object> CallGetterIfAccessor( TNode<Object> CallGetterIfAccessor(TNode<Object> value,
TNode<Object> value, TNode<HeapObject> holder, TNode<Uint32T> details, TNode<HeapObject> holder,
TNode<Context> context, TNode<Object> receiver, TNode<Object> name, TNode<Uint32T> details,
Label* if_bailout, GetOwnPropertyMode mode = kCallJSGetter); TNode<Context> context,
TNode<Object> receiver, Label* if_bailout,
GetOwnPropertyMode mode = kCallJSGetter);
TNode<IntPtrT> TryToIntptr(TNode<Object> key, Label* if_not_intptr, TNode<IntPtrT> TryToIntptr(TNode<Object> key, Label* if_not_intptr,
TVariable<Int32T>* var_instance_type = nullptr); TVariable<Int32T>* var_instance_type = nullptr);
......
...@@ -43,22 +43,6 @@ MaybeHandle<Object> DebugEvaluate::Global(Isolate* isolate, ...@@ -43,22 +43,6 @@ MaybeHandle<Object> DebugEvaluate::Global(Isolate* isolate,
Handle<String> source, Handle<String> source,
debug::EvaluateGlobalMode mode, debug::EvaluateGlobalMode mode,
REPLMode repl_mode) { REPLMode repl_mode) {
Handle<SharedFunctionInfo> shared_info;
if (!GetFunctionInfo(isolate, source, repl_mode).ToHandle(&shared_info)) {
return MaybeHandle<Object>();
}
Handle<NativeContext> context = isolate->native_context();
Handle<JSFunction> fun =
Factory::JSFunctionBuilder{isolate, shared_info, context}.Build();
return Global(isolate, fun, mode, repl_mode);
}
MaybeHandle<Object> DebugEvaluate::Global(Isolate* isolate,
Handle<JSFunction> function,
debug::EvaluateGlobalMode mode,
REPLMode repl_mode) {
// Disable breaks in side-effect free mode. // Disable breaks in side-effect free mode.
DisableBreak disable_break_scope( DisableBreak disable_break_scope(
isolate->debug(), isolate->debug(),
...@@ -66,14 +50,19 @@ MaybeHandle<Object> DebugEvaluate::Global(Isolate* isolate, ...@@ -66,14 +50,19 @@ MaybeHandle<Object> DebugEvaluate::Global(Isolate* isolate,
mode == mode ==
debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect); debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect);
Handle<NativeContext> context = isolate->native_context(); Handle<SharedFunctionInfo> shared_info;
CHECK_EQ(function->native_context(), *context); if (!GetFunctionInfo(isolate, source, repl_mode).ToHandle(&shared_info)) {
return MaybeHandle<Object>();
}
Handle<Context> context = isolate->native_context();
Handle<JSFunction> fun =
Factory::JSFunctionBuilder{isolate, shared_info, context}.Build();
if (mode == debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) { if (mode == debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) {
isolate->debug()->StartSideEffectCheckMode(); isolate->debug()->StartSideEffectCheckMode();
} }
MaybeHandle<Object> result = Execution::Call( MaybeHandle<Object> result = Execution::Call(
isolate, function, Handle<JSObject>(context->global_proxy(), isolate), 0, isolate, fun, Handle<JSObject>(context->global_proxy(), isolate), 0,
nullptr); nullptr);
if (mode == debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) { if (mode == debug::EvaluateGlobalMode::kDisableBreaksAndThrowOnSideEffect) {
isolate->debug()->StopSideEffectCheckMode(); isolate->debug()->StopSideEffectCheckMode();
......
...@@ -27,10 +27,6 @@ class DebugEvaluate : public AllStatic { ...@@ -27,10 +27,6 @@ class DebugEvaluate : public AllStatic {
debug::EvaluateGlobalMode mode, debug::EvaluateGlobalMode mode,
REPLMode repl_mode = REPLMode::kNo); REPLMode repl_mode = REPLMode::kNo);
static V8_EXPORT_PRIVATE MaybeHandle<Object> Global(
Isolate* isolate, Handle<JSFunction> function,
debug::EvaluateGlobalMode mode, REPLMode repl_mode = REPLMode::kNo);
// Evaluate a piece of JavaScript in the context of a stack frame for // Evaluate a piece of JavaScript in the context of a stack frame for
// debugging. Things that need special attention are: // debugging. Things that need special attention are:
// - Parameters and stack-allocated locals need to be materialized. Altered // - Parameters and stack-allocated locals need to be materialized. Altered
......
...@@ -777,34 +777,6 @@ void FixedArray::FixedArrayPrint(std::ostream& os) { ...@@ -777,34 +777,6 @@ void FixedArray::FixedArrayPrint(std::ostream& os) {
PrintFixedArrayWithHeader(os, *this, "FixedArray"); PrintFixedArrayWithHeader(os, *this, "FixedArray");
} }
namespace {
const char* SideEffectType2String(SideEffectType type) {
switch (type) {
case SideEffectType::kHasSideEffect:
return "kHasSideEffect";
case SideEffectType::kHasNoSideEffect:
return "kHasNoSideEffect";
case SideEffectType::kHasSideEffectToReceiver:
return "kHasSideEffectToReceiver";
}
}
} // namespace
void AccessorInfo::AccessorInfoPrint(std::ostream& os) {
TorqueGeneratedAccessorInfo<AccessorInfo, Struct>::AccessorInfoPrint(os);
os << " - all_can_read: " << all_can_read();
os << "\n - all_can_write: " << all_can_write();
os << "\n - is_special_data_property: " << is_special_data_property();
os << "\n - is_sloppy: " << is_sloppy();
os << "\n - replace_on_access: " << replace_on_access();
os << "\n - getter_side_effect_type: "
<< SideEffectType2String(getter_side_effect_type());
os << "\n - setter_side_effect_type: "
<< SideEffectType2String(setter_side_effect_type());
os << "\n - initial_attributes: " << initial_property_attributes();
os << '\n';
}
namespace { namespace {
void PrintContextWithHeader(std::ostream& os, Context context, void PrintContextWithHeader(std::ostream& os, Context context,
const char* type) { const char* type) {
...@@ -2805,22 +2777,6 @@ V8_EXPORT_PRIVATE extern void _v8_internal_Print_Object(void* object) { ...@@ -2805,22 +2777,6 @@ V8_EXPORT_PRIVATE extern void _v8_internal_Print_Object(void* object) {
GetObjectFromRaw(object).Print(); GetObjectFromRaw(object).Print();
} }
V8_EXPORT_PRIVATE extern void _v8_internal_Print_LoadHandler(void* object) {
#ifdef OBJECT_PRINT
i::StdoutStream os;
i::LoadHandler::PrintHandler(GetObjectFromRaw(object), os);
os << std::flush;
#endif
}
V8_EXPORT_PRIVATE extern void _v8_internal_Print_StoreHandler(void* object) {
#ifdef OBJECT_PRINT
i::StdoutStream os;
i::StoreHandler::PrintHandler(GetObjectFromRaw(object), os);
os << std::flush;
#endif
}
V8_EXPORT_PRIVATE extern void _v8_internal_Print_Code(void* object) { V8_EXPORT_PRIVATE extern void _v8_internal_Print_Code(void* object) {
i::Address address = reinterpret_cast<i::Address>(object); i::Address address = reinterpret_cast<i::Address>(object);
i::Isolate* isolate = i::Isolate::Current(); i::Isolate* isolate = i::Isolate::Current();
......
...@@ -594,7 +594,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( ...@@ -594,7 +594,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase(
properties, var_name_index.value(), &var_details, &var_value); properties, var_name_index.value(), &var_details, &var_value);
TNode<Object> value = CallGetterIfAccessor( TNode<Object> value = CallGetterIfAccessor(
var_value.value(), CAST(holder), var_details.value(), p->context(), var_value.value(), CAST(holder), var_details.value(), p->context(),
p->receiver(), p->name(), miss); p->receiver(), miss);
exit_point->Return(value); exit_point->Return(value);
} }
} }
...@@ -614,17 +614,11 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( ...@@ -614,17 +614,11 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase(
} }
BIND(&native_data_property); BIND(&native_data_property);
{ HandleLoadCallbackProperty(p, CAST(holder), handler_word, exit_point);
GotoIf(IsSideEffectFreeDebuggingActive(), &slow);
HandleLoadCallbackProperty(p, CAST(holder), handler_word, exit_point);
}
BIND(&api_getter); BIND(&api_getter);
{ HandleLoadAccessor(p, CAST(holder), handler_word, CAST(handler), handler_kind,
GotoIf(IsSideEffectFreeDebuggingActive(), &slow); exit_point);
HandleLoadAccessor(p, CAST(holder), handler_word, CAST(handler),
handler_kind, exit_point);
}
BIND(&proxy); BIND(&proxy);
{ {
...@@ -684,8 +678,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase( ...@@ -684,8 +678,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerLoadNamedCase(
GotoIf(IsTheHole(value), miss); GotoIf(IsTheHole(value), miss);
exit_point->Return(CallGetterIfAccessor(value, CAST(holder), details, exit_point->Return(CallGetterIfAccessor(value, CAST(holder), details,
p->context(), p->receiver(), p->context(), p->receiver(), miss));
p->name(), miss));
} }
BIND(&interceptor); BIND(&interceptor);
...@@ -971,7 +964,7 @@ void AccessorAssembler::HandleLoadICProtoHandler( ...@@ -971,7 +964,7 @@ void AccessorAssembler::HandleLoadICProtoHandler(
properties, name_index, &var_details, &var_value); properties, name_index, &var_details, &var_value);
TNode<Object> value = CallGetterIfAccessor( TNode<Object> value = CallGetterIfAccessor(
var_value.value(), CAST(var_holder->value()), var_details.value(), var_value.value(), CAST(var_holder->value()), var_details.value(),
p->context(), p->receiver(), p->name(), miss); p->context(), p->receiver(), miss);
exit_point->Return(value); exit_point->Return(value);
} }
}, },
...@@ -1744,12 +1737,9 @@ void AccessorAssembler::HandleStoreICProtoHandler( ...@@ -1744,12 +1737,9 @@ void AccessorAssembler::HandleStoreICProtoHandler(
Goto(&store); Goto(&store);
BIND(&store); BIND(&store);
{ TNode<IntPtrT> argc = IntPtrConstant(1);
GotoIf(IsSideEffectFreeDebuggingActive(), &if_slow); Return(CallApiCallback(context, callback, argc, data, api_holder.value(),
TNode<IntPtrT> argc = IntPtrConstant(1); p->receiver(), p->value()));
Return(CallApiCallback(context, callback, argc, data,
api_holder.value(), p->receiver(), p->value()));
}
} }
BIND(&if_store_global_proxy); BIND(&if_store_global_proxy);
...@@ -2571,7 +2561,7 @@ void AccessorAssembler::GenericPropertyLoad( ...@@ -2571,7 +2561,7 @@ void AccessorAssembler::GenericPropertyLoad(
{ {
TNode<Object> value = CallGetterIfAccessor( TNode<Object> value = CallGetterIfAccessor(
var_value.value(), lookup_start_object, var_details.value(), var_value.value(), lookup_start_object, var_details.value(),
p->context(), p->receiver(), p->name(), slow); p->context(), p->receiver(), slow);
IncrementCounter(isolate()->counters()->ic_keyed_load_generic_symbol(), 1); IncrementCounter(isolate()->counters()->ic_keyed_load_generic_symbol(), 1);
Return(value); Return(value);
} }
......
...@@ -64,8 +64,6 @@ class AccessorInfo : public TorqueGeneratedAccessorInfo<AccessorInfo, Struct> { ...@@ -64,8 +64,6 @@ class AccessorInfo : public TorqueGeneratedAccessorInfo<AccessorInfo, Struct> {
static int AppendUnique(Isolate* isolate, Handle<Object> descriptors, static int AppendUnique(Isolate* isolate, Handle<Object> descriptors,
Handle<FixedArray> array, int valid_descriptors); Handle<FixedArray> array, int valid_descriptors);
DECL_PRINTER(AccessorInfo)
private: private:
inline bool HasExpectedReceiverType(); inline bool HasExpectedReceiverType();
......
This diff is collapsed.
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