Commit fb2768bd authored by Benedikt Meurer's avatar Benedikt Meurer Committed by Commit Bot

[debug] Mark side-effect free builtins and intrinsics as such.

While working on C++ debug evaluate, we found that several builtins and
intrinsics aren't marked as side effect free, although they are clearly
side effect free, and that breaks the C++ side effect free evaluation.

- %DefineClass() and %TypedArray%.of(), and
- various WebAssembly getters ("buffer", "exports" and "length") as
  well as the C++ functions for the debug proxy.

Also-By: pfaffe@chromium.org
Bug: chromium:1137514
Change-Id: Iebd333dc2014f1ad218908f64c9199c157dc08b5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2565135Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71498}
parent 94f05366
...@@ -346,6 +346,7 @@ bool IntrinsicHasNoSideEffect(Runtime::FunctionId id) { ...@@ -346,6 +346,7 @@ bool IntrinsicHasNoSideEffect(Runtime::FunctionId id) {
V(CreateObjectLiteral) \ V(CreateObjectLiteral) \
V(CreateObjectLiteralWithoutAllocationSite) \ V(CreateObjectLiteralWithoutAllocationSite) \
V(CreateRegExpLiteral) \ V(CreateRegExpLiteral) \
V(DefineClass) \
/* Called from builtins */ \ /* Called from builtins */ \
V(AllocateInYoungGeneration) \ V(AllocateInYoungGeneration) \
V(AllocateInOldGeneration) \ V(AllocateInOldGeneration) \
...@@ -593,6 +594,7 @@ DebugInfo::SideEffectState BuiltinGetSideEffectState(Builtins::Name id) { ...@@ -593,6 +594,7 @@ DebugInfo::SideEffectState BuiltinGetSideEffectState(Builtins::Name id) {
case Builtins::kTrace: case Builtins::kTrace:
// TypedArray builtins. // TypedArray builtins.
case Builtins::kTypedArrayConstructor: case Builtins::kTypedArrayConstructor:
case Builtins::kTypedArrayOf:
case Builtins::kTypedArrayPrototypeAt: case Builtins::kTypedArrayPrototypeAt:
case Builtins::kTypedArrayPrototypeBuffer: case Builtins::kTypedArrayPrototypeBuffer:
case Builtins::kTypedArrayPrototypeByteLength: case Builtins::kTypedArrayPrototypeByteLength:
......
...@@ -1992,9 +1992,11 @@ void WebAssemblyGlobalType(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -1992,9 +1992,11 @@ void WebAssemblyGlobalType(const v8::FunctionCallbackInfo<v8::Value>& args) {
// TODO(titzer): we use the API to create the function template because the // TODO(titzer): we use the API to create the function template because the
// internal guts are too ugly to replicate here. // internal guts are too ugly to replicate here.
static i::Handle<i::FunctionTemplateInfo> NewFunctionTemplate( static i::Handle<i::FunctionTemplateInfo> NewFunctionTemplate(
i::Isolate* i_isolate, FunctionCallback func, bool has_prototype) { i::Isolate* i_isolate, FunctionCallback func, bool has_prototype,
SideEffectType side_effect_type = SideEffectType::kHasSideEffect) {
Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate); Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate);
Local<FunctionTemplate> templ = FunctionTemplate::New(isolate, func); Local<FunctionTemplate> templ = FunctionTemplate::New(
isolate, func, {}, {}, 0, ConstructorBehavior::kAllow, side_effect_type);
has_prototype ? templ->ReadOnlyPrototype() : templ->RemovePrototype(); has_prototype ? templ->ReadOnlyPrototype() : templ->RemovePrototype();
return v8::Utils::OpenHandle(*templ); return v8::Utils::OpenHandle(*templ);
} }
...@@ -2008,22 +2010,26 @@ static i::Handle<i::ObjectTemplateInfo> NewObjectTemplate( ...@@ -2008,22 +2010,26 @@ static i::Handle<i::ObjectTemplateInfo> NewObjectTemplate(
namespace internal { namespace internal {
Handle<JSFunction> CreateFunc(Isolate* isolate, Handle<String> name, Handle<JSFunction> CreateFunc(
FunctionCallback func, bool has_prototype) { Isolate* isolate, Handle<String> name, FunctionCallback func,
bool has_prototype,
SideEffectType side_effect_type = SideEffectType::kHasSideEffect) {
Handle<FunctionTemplateInfo> temp = Handle<FunctionTemplateInfo> temp =
NewFunctionTemplate(isolate, func, has_prototype); NewFunctionTemplate(isolate, func, has_prototype, side_effect_type);
Handle<JSFunction> function = Handle<JSFunction> function =
ApiNatives::InstantiateFunction(temp, name).ToHandleChecked(); ApiNatives::InstantiateFunction(temp, name).ToHandleChecked();
DCHECK(function->shared().HasSharedName()); DCHECK(function->shared().HasSharedName());
return function; return function;
} }
Handle<JSFunction> InstallFunc(Isolate* isolate, Handle<JSObject> object, Handle<JSFunction> InstallFunc(
const char* str, FunctionCallback func, Isolate* isolate, Handle<JSObject> object, const char* str,
int length, bool has_prototype = false, FunctionCallback func, int length, bool has_prototype = false,
PropertyAttributes attributes = NONE) { PropertyAttributes attributes = NONE,
SideEffectType side_effect_type = SideEffectType::kHasSideEffect) {
Handle<String> name = v8_str(isolate, str); Handle<String> name = v8_str(isolate, str);
Handle<JSFunction> function = CreateFunc(isolate, name, func, has_prototype); Handle<JSFunction> function =
CreateFunc(isolate, name, func, has_prototype, side_effect_type);
function->shared().set_length(length); function->shared().set_length(length);
JSObject::AddProperty(isolate, object, name, function, attributes); JSObject::AddProperty(isolate, object, name, function, attributes);
return function; return function;
...@@ -2045,7 +2051,8 @@ void InstallGetter(Isolate* isolate, Handle<JSObject> object, const char* str, ...@@ -2045,7 +2051,8 @@ void InstallGetter(Isolate* isolate, Handle<JSObject> object, const char* str,
FunctionCallback func) { FunctionCallback func) {
Handle<String> name = v8_str(isolate, str); Handle<String> name = v8_str(isolate, str);
Handle<JSFunction> function = Handle<JSFunction> function =
CreateFunc(isolate, GetterName(isolate, name), func, false); CreateFunc(isolate, GetterName(isolate, name), func, false,
SideEffectType::kHasNoSideEffect);
Utils::ToLocal(object)->SetAccessorProperty(Utils::ToLocal(name), Utils::ToLocal(object)->SetAccessorProperty(Utils::ToLocal(name),
Utils::ToLocal(function), Utils::ToLocal(function),
...@@ -2942,8 +2949,10 @@ Handle<JSProxy> GetJSProxy( ...@@ -2942,8 +2949,10 @@ Handle<JSProxy> GetJSProxy(
Handle<BigInt> callee_fp = BigInt::FromInt64(isolate, frame->callee_fp()); Handle<BigInt> callee_fp = BigInt::FromInt64(isolate, frame->callee_fp());
JSObject::AddProperty(isolate, handler, "callee_fp", callee_fp, DONT_ENUM); JSObject::AddProperty(isolate, handler, "callee_fp", callee_fp, DONT_ENUM);
InstallFunc(isolate, handler, "get", get_callback, 3, false, READ_ONLY); InstallFunc(isolate, handler, "get", get_callback, 3, false, READ_ONLY,
InstallFunc(isolate, handler, "has", has_callback, 2, false, READ_ONLY); SideEffectType::kHasNoSideEffect);
InstallFunc(isolate, handler, "has", has_callback, 2, false, READ_ONLY,
SideEffectType::kHasNoSideEffect);
return factory->NewJSProxy(target, handler); return factory->NewJSProxy(target, handler);
} }
...@@ -3007,9 +3016,9 @@ Handle<JSProxy> WasmJs::GetJSDebugProxy(WasmFrame* frame) { ...@@ -3007,9 +3016,9 @@ Handle<JSProxy> WasmJs::GetJSDebugProxy(WasmFrame* frame) {
// The top level proxy delegates lookups to the index space proxies. // The top level proxy delegates lookups to the index space proxies.
Handle<JSObject> handler = factory->NewJSObjectWithNullProto(); Handle<JSObject> handler = factory->NewJSObjectWithNullProto();
InstallFunc(isolate, handler, "get", ToplevelGetTrapCallback, 3, false, InstallFunc(isolate, handler, "get", ToplevelGetTrapCallback, 3, false,
READ_ONLY); READ_ONLY, SideEffectType::kHasNoSideEffect);
InstallFunc(isolate, handler, "has", ToplevelHasTrapCallback, 2, false, InstallFunc(isolate, handler, "has", ToplevelHasTrapCallback, 2, false,
READ_ONLY); READ_ONLY, SideEffectType::kHasNoSideEffect);
Handle<JSObject> target = factory->NewJSObjectWithNullProto(); Handle<JSObject> target = factory->NewJSObjectWithNullProto();
......
...@@ -121,7 +121,7 @@ function listener(event, exec_state, event_data, data) { ...@@ -121,7 +121,7 @@ function listener(event, exec_state, event_data, data) {
success(true, `!!typed_array.buffer`); success(true, `!!typed_array.buffer`);
success(0, `typed_array.byteOffset`); success(0, `typed_array.byteOffset`);
success(3, `typed_array.byteLength`); success(3, `typed_array.byteLength`);
fail(`Uint8Array.of(1, 2)`); success({0: 1, 1: 2}, `Uint8Array.of(1, 2)`);
function_param = [ function_param = [
"forEach", "every", "some", "reduce", "reduceRight", "find", "filter", "forEach", "every", "some", "reduce", "reduceRight", "find", "filter",
"map", "findIndex" "map", "findIndex"
......
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