Commit 669bfe46 authored by Simon Zünd's avatar Simon Zünd Committed by Commit Bot

[csa] Expose debug_execution_mode to CSA

This CL does two things: It adds a CSA helper to determine whether
the debug_execution_mode is kSideEffects. And it adds a runtime
function that exposes PerformSideEffectCheckForObject.

This will be needed for the Array.p.unshift Torque version.

R=jgruber@chromium.org

Change-Id: Idc1ae077956e0862e613a2c28af3f2cf4d5c3762
Reviewed-on: https://chromium-review.googlesource.com/1196362
Commit-Queue: Simon Zünd <szuend@google.com>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55577}
parent a45a20e4
...@@ -1132,6 +1132,19 @@ void CodeStubAssembler::GotoIfForceSlowPath(Label* if_true) { ...@@ -1132,6 +1132,19 @@ void CodeStubAssembler::GotoIfForceSlowPath(Label* if_true) {
#endif #endif
} }
void CodeStubAssembler::GotoIfDebugExecutionModeChecksSideEffects(
Label* if_true) {
STATIC_ASSERT(sizeof(DebugInfo::ExecutionMode) >= sizeof(int32_t));
TNode<ExternalReference> execution_mode_address = ExternalConstant(
ExternalReference::debug_execution_mode_address(isolate()));
TNode<Int32T> execution_mode =
UncheckedCast<Int32T>(Load(MachineType::Int32(), execution_mode_address));
GotoIf(Word32Equal(execution_mode, Int32Constant(DebugInfo::kSideEffects)),
if_true);
}
Node* CodeStubAssembler::AllocateRaw(Node* size_in_bytes, AllocationFlags flags, Node* CodeStubAssembler::AllocateRaw(Node* size_in_bytes, AllocationFlags flags,
Node* top_address, Node* limit_address) { Node* top_address, Node* limit_address) {
// TODO(jgruber, chromium:848672): TNodeify AllocateRaw. // TODO(jgruber, chromium:848672): TNodeify AllocateRaw.
......
...@@ -769,6 +769,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { ...@@ -769,6 +769,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
// Works only with V8_ENABLE_FORCE_SLOW_PATH compile time flag. Nop otherwise. // Works only with V8_ENABLE_FORCE_SLOW_PATH compile time flag. Nop otherwise.
void GotoIfForceSlowPath(Label* if_true); void GotoIfForceSlowPath(Label* if_true);
// Branches to {if_true} when Debug::ExecutionMode is DebugInfo::kSideEffect.
void GotoIfDebugExecutionModeChecksSideEffects(Label* if_true);
// Load value from current frame by given offset in bytes. // Load value from current frame by given offset in bytes.
Node* LoadFromFrame(int offset, MachineType rep = MachineType::AnyTagged()); Node* LoadFromFrame(int offset, MachineType rep = MachineType::AnyTagged());
// Load value from current parent frame by given offset in bytes. // Load value from current parent frame by given offset in bytes.
......
...@@ -841,6 +841,11 @@ ExternalReference::promise_hook_or_async_event_delegate_address( ...@@ -841,6 +841,11 @@ ExternalReference::promise_hook_or_async_event_delegate_address(
isolate->promise_hook_or_async_event_delegate_address()); isolate->promise_hook_or_async_event_delegate_address());
} }
ExternalReference ExternalReference::debug_execution_mode_address(
Isolate* isolate) {
return ExternalReference(isolate->debug_execution_mode_address());
}
ExternalReference ExternalReference::debug_is_active_address(Isolate* isolate) { ExternalReference ExternalReference::debug_is_active_address(Isolate* isolate) {
return ExternalReference(isolate->debug()->is_active_address()); return ExternalReference(isolate->debug()->is_active_address());
} }
......
...@@ -57,6 +57,7 @@ class StatsCounter; ...@@ -57,6 +57,7 @@ class StatsCounter;
V(async_event_delegate_address, "Isolate::async_event_delegate_address()") \ V(async_event_delegate_address, "Isolate::async_event_delegate_address()") \
V(promise_hook_or_async_event_delegate_address, \ V(promise_hook_or_async_event_delegate_address, \
"Isolate::promise_hook_or_async_event_delegate_address()") \ "Isolate::promise_hook_or_async_event_delegate_address()") \
V(debug_execution_mode_address, "Isolate::debug_execution_mode_address()") \
V(debug_is_active_address, "Debug::is_active_address()") \ V(debug_is_active_address, "Debug::is_active_address()") \
V(debug_hook_on_function_call_address, \ V(debug_hook_on_function_call_address, \
"Debug::hook_on_function_call_address()") \ "Debug::hook_on_function_call_address()") \
......
...@@ -1322,6 +1322,10 @@ class Isolate : private HiddenFactory { ...@@ -1322,6 +1322,10 @@ class Isolate : private HiddenFactory {
bool force_slow_path() const { return force_slow_path_; } bool force_slow_path() const { return force_slow_path_; }
bool* force_slow_path_address() { return &force_slow_path_; } bool* force_slow_path_address() { return &force_slow_path_; }
DebugInfo::ExecutionMode* debug_execution_mode_address() {
return &debug_execution_mode_;
}
V8_EXPORT_PRIVATE base::RandomNumberGenerator* random_number_generator(); V8_EXPORT_PRIVATE base::RandomNumberGenerator* random_number_generator();
V8_EXPORT_PRIVATE base::RandomNumberGenerator* fuzzer_rng(); V8_EXPORT_PRIVATE base::RandomNumberGenerator* fuzzer_rng();
......
...@@ -810,5 +810,19 @@ RUNTIME_FUNCTION(Runtime_LiveEditPatchScript) { ...@@ -810,5 +810,19 @@ RUNTIME_FUNCTION(Runtime_LiveEditPatchScript) {
} }
return ReadOnlyRoots(isolate).undefined_value(); return ReadOnlyRoots(isolate).undefined_value();
} }
RUNTIME_FUNCTION(Runtime_PerformSideEffectCheckForObject) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
DCHECK_EQ(isolate->debug_execution_mode(), DebugInfo::kSideEffects);
if (!isolate->debug()->PerformSideEffectCheckForObject(object)) {
DCHECK(isolate->has_pending_exception());
return ReadOnlyRoots(isolate).exception();
}
return ReadOnlyRoots(isolate).undefined_value();
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -340,6 +340,7 @@ namespace internal { ...@@ -340,6 +340,7 @@ namespace internal {
F(ObjectValues, 1, 1) \ F(ObjectValues, 1, 1) \
F(ObjectValuesSkipFastPath, 1, 1) \ F(ObjectValuesSkipFastPath, 1, 1) \
F(OptimizeObjectForAddingMultipleProperties, 2, 1) \ F(OptimizeObjectForAddingMultipleProperties, 2, 1) \
F(PerformSideEffectCheckForObject, 1, 1) \
F(SameValue, 2, 1) \ F(SameValue, 2, 1) \
F(SameValueZero, 2, 1) \ F(SameValueZero, 2, 1) \
F(SetDataProperties, 2, 1) \ F(SetDataProperties, 2, 1) \
......
...@@ -3503,6 +3503,37 @@ TEST(TestCallBuiltinIndirectLoad) { ...@@ -3503,6 +3503,37 @@ TEST(TestCallBuiltinIndirectLoad) {
Handle<String>::cast(result.ToHandleChecked()))); Handle<String>::cast(result.ToHandleChecked())));
} }
TEST(TestGotoIfDebugExecutionModeChecksSideEffects) {
Isolate* isolate(CcTest::InitIsolateOnce());
CodeAssemblerTester asm_tester(isolate, 0);
{
CodeStubAssembler m(asm_tester.state());
Label is_true(&m), is_false(&m);
m.GotoIfDebugExecutionModeChecksSideEffects(&is_true);
m.Goto(&is_false);
m.BIND(&is_false);
m.Return(m.BooleanConstant(false));
m.BIND(&is_true);
m.Return(m.BooleanConstant(true));
}
FunctionTester ft(asm_tester.GenerateCode(), 0);
CHECK(isolate->debug_execution_mode() != DebugInfo::kSideEffects);
Handle<Object> result = ft.Call().ToHandleChecked();
CHECK(result->IsBoolean());
CHECK_EQ(false, result->BooleanValue(isolate));
isolate->debug()->StartSideEffectCheckMode();
CHECK(isolate->debug_execution_mode() == DebugInfo::kSideEffects);
result = ft.Call().ToHandleChecked();
CHECK(result->IsBoolean());
CHECK_EQ(true, result->BooleanValue(isolate));
}
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
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