Skip to content

Commit ebb7e10

Browse files
alexmarkovCommit Queue
authored andcommitted
[vm] Use _setjmp instead of setjmp on MacOS/iOS
setjmp is extremely expensive on MacOS/iOS as it always saves signal mask. Introduce DART_SETJMP / DART_LONGJMP macros to use _setjmp instead of setjmp on MacOS/iOS. DeltaBlue on Mac/arm64 on the interpreter: 179585.3 us -> 58347.9 us. (3x faster) TEST=ci Issue: #60205 Change-Id: I2122f2eb4d5de66ae2ef904a7034af1ed09f1d07 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/412320 Reviewed-by: Ryan Macnak <[email protected]> Commit-Queue: Alexander Markov <[email protected]>
1 parent 462bcaf commit ebb7e10

24 files changed

+48
-39
lines changed

runtime/platform/globals.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,15 @@ struct simd128_value_t {
297297
#error Automatic compiler detection failed.
298298
#endif
299299

300+
#if defined(__APPLE__)
301+
// Avoid expensive saving of sigmask in setjmp/longjmp.
302+
#define DART_SETJMP _setjmp
303+
#define DART_LONGJMP _longjmp
304+
#else
305+
#define DART_SETJMP setjmp
306+
#define DART_LONGJMP longjmp
307+
#endif
308+
300309
#if !defined(TARGET_ARCH_ARM) && !defined(TARGET_ARCH_X64) && \
301310
!defined(TARGET_ARCH_IA32) && !defined(TARGET_ARCH_ARM64) && \
302311
!defined(TARGET_ARCH_RISCV32) && !defined(TARGET_ARCH_RISCV64)

runtime/vm/allocation_test.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ static void StackAllocatedLongJumpHelper(int* ptr, LongJumpScope* jump) {
9292
ISOLATE_UNIT_TEST_CASE(StackAllocatedLongJump) {
9393
LongJumpScope jump;
9494
int data = 1;
95-
if (setjmp(*jump.Set()) == 0) {
95+
if (DART_SETJMP(*jump.Set()) == 0) {
9696
StackAllocatedLongJumpHelper(&data, &jump);
9797
UNREACHABLE();
9898
} else {
@@ -145,7 +145,7 @@ ISOLATE_UNIT_TEST_CASE(StackResourceLongJump) {
145145
{
146146
LongJumpScope jump;
147147
int data = 1;
148-
if (setjmp(*jump.Set()) == 0) {
148+
if (DART_SETJMP(*jump.Set()) == 0) {
149149
StackResourceLongJumpHelper(&data, &jump);
150150
UNREACHABLE();
151151
} else {

runtime/vm/bootstrap.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ static ErrorPtr BootstrapFromKernelSingleProgram(
114114
std::unique_ptr<kernel::Program> program) {
115115
Zone* zone = thread->zone();
116116
LongJumpScope jump;
117-
if (setjmp(*jump.Set()) == 0) {
117+
if (DART_SETJMP(*jump.Set()) == 0) {
118118
kernel::KernelLoader loader(program.get(), /*uri_to_source_table=*/nullptr);
119119

120120
auto isolate_group = thread->isolate_group();

runtime/vm/class_finalizer.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ bool ClassFinalizer::ProcessPendingClasses() {
199199
}
200200

201201
LongJumpScope jump;
202-
if (setjmp(*jump.Set()) == 0) {
202+
if (DART_SETJMP(*jump.Set()) == 0) {
203203
GrowableObjectArray& class_array = GrowableObjectArray::Handle();
204204
class_array = object_store->pending_classes();
205205
ASSERT(!class_array.IsNull());
@@ -827,7 +827,7 @@ ErrorPtr ClassFinalizer::LoadClassMembers(const Class& cls) {
827827
ASSERT(!cls.is_finalized());
828828

829829
LongJumpScope jump;
830-
if (setjmp(*jump.Set()) == 0) {
830+
if (DART_SETJMP(*jump.Set()) == 0) {
831831
cls.EnsureDeclarationLoaded();
832832
ASSERT(cls.is_type_finalized());
833833
ClassFinalizer::FinalizeClass(cls);

runtime/vm/compiler/aot/precompiler.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ static void Jump(const Error& error) {
364364

365365
ErrorPtr Precompiler::CompileAll() {
366366
LongJumpScope jump;
367-
if (setjmp(*jump.Set()) == 0) {
367+
if (DART_SETJMP(*jump.Set()) == 0) {
368368
Precompiler precompiler(Thread::Current());
369369
precompiler.DoCompileAll();
370370
precompiler.ReportStats();
@@ -3486,7 +3486,7 @@ bool PrecompileParsedFunctionHelper::GenerateCode(FlowGraph* flow_graph) {
34863486

34873487
while (!done) {
34883488
LongJumpScope jump;
3489-
const intptr_t val = setjmp(*jump.Set());
3489+
const intptr_t val = DART_SETJMP(*jump.Set());
34903490
if (val == 0) {
34913491
// Even in bare instructions mode we don't directly add objects into
34923492
// the global object pool because code generation can bail out

runtime/vm/compiler/backend/inliner.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1278,7 +1278,7 @@ class CallSiteInliner : public ValueObject {
12781278

12791279
// Install bailout jump.
12801280
LongJumpScope jump;
1281-
if (setjmp(*jump.Set()) == 0) {
1281+
if (DART_SETJMP(*jump.Set()) == 0) {
12821282
// Load IC data for the callee.
12831283
ZoneGrowableArray<const ICData*>* ic_data_array =
12841284
new (Z) ZoneGrowableArray<const ICData*>();

runtime/vm/compiler/jit/compiler.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ CodePtr CompileParsedFunctionHelper::Compile() {
498498
while (!done) {
499499
*result = Code::null();
500500
LongJumpScope jump;
501-
if (setjmp(*jump.Set()) == 0) {
501+
if (DART_SETJMP(*jump.Set()) == 0) {
502502
FlowGraph* flow_graph = nullptr;
503503
ZoneGrowableArray<const ICData*>* ic_data_array = nullptr;
504504

@@ -673,7 +673,7 @@ static ObjectPtr CompileFunctionHelper(const Function& function,
673673
ASSERT(!FLAG_precompiled_mode);
674674
ASSERT(!optimized || function.WasCompiled() || function.ForceOptimize());
675675
LongJumpScope jump;
676-
if (setjmp(*jump.Set()) == 0) {
676+
if (DART_SETJMP(*jump.Set()) == 0) {
677677
StackZone stack_zone(thread);
678678
Zone* const zone = stack_zone.GetZone();
679679
const bool trace_compiler =
@@ -889,7 +889,7 @@ void Compiler::ComputeLocalVarDescriptors(const Code& code) {
889889
Zone* zone = thread->zone();
890890
CompilerState state(thread, /*is_aot=*/false, /*is_optimizing=*/false);
891891
LongJumpScope jump;
892-
if (setjmp(*jump.Set()) == 0) {
892+
if (DART_SETJMP(*jump.Set()) == 0) {
893893
ParsedFunction* parsed_function =
894894
new ParsedFunction(thread, Function::ZoneHandle(zone, function.ptr()));
895895
ZoneGrowableArray<const ICData*>* ic_data_array =

runtime/vm/exceptions.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,7 @@ NO_SANITIZE_SAFE_STACK // This function manipulates the safestack pointer.
671671
tsan_utils->exception_pc = program_counter;
672672
tsan_utils->exception_sp = stack_pointer;
673673
tsan_utils->exception_fp = frame_pointer;
674-
longjmp(*(tsan_utils->setjmp_buffer), 1);
674+
DART_LONGJMP(*(tsan_utils->setjmp_buffer), 1);
675675
}
676676
#endif // defined(USING_THREAD_SANITIZER)
677677

runtime/vm/heap/scavenger.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ class ScavengerVisitorBase : public ObjectPointerVisitor,
282282
page_space_->AcquireLock(freelist_);
283283

284284
LongJumpScope jump(thread_);
285-
if (setjmp(*jump.Set()) == 0) {
285+
if (DART_SETJMP(*jump.Set()) == 0) {
286286
scavenger_->IterateRoots(this);
287287
} else {
288288
ASSERT(scavenger_->abort_);
@@ -291,7 +291,7 @@ class ScavengerVisitorBase : public ObjectPointerVisitor,
291291

292292
void ProcessSurvivors() {
293293
LongJumpScope jump(thread_);
294-
if (setjmp(*jump.Set()) == 0) {
294+
if (DART_SETJMP(*jump.Set()) == 0) {
295295
// Iterate until all work has been drained.
296296
do {
297297
ProcessToSpace();
@@ -305,7 +305,7 @@ class ScavengerVisitorBase : public ObjectPointerVisitor,
305305
void ProcessAll() {
306306
TIMELINE_FUNCTION_GC_DURATION(thread_, "ProcessToSpace");
307307
LongJumpScope jump(thread_);
308-
if (setjmp(*jump.Set()) == 0) {
308+
if (DART_SETJMP(*jump.Set()) == 0) {
309309
do {
310310
do {
311311
ProcessToSpace();
@@ -320,7 +320,7 @@ class ScavengerVisitorBase : public ObjectPointerVisitor,
320320

321321
void ProcessWeakProperties() {
322322
LongJumpScope jump(thread_);
323-
if (setjmp(*jump.Set()) == 0) {
323+
if (DART_SETJMP(*jump.Set()) == 0) {
324324
ProcessWeakPropertiesScoped();
325325
} else {
326326
ASSERT(scavenger_->abort_);

runtime/vm/interpreter.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class InterpreterSetjmpBuffer {
5151
void Longjmp() {
5252
// "This" is now the last setjmp buffer.
5353
interpreter_->set_last_setjmp_buffer(this);
54-
longjmp(buffer_, 1);
54+
DART_LONGJMP(buffer_, 1);
5555
}
5656

5757
explicit InterpreterSetjmpBuffer(Interpreter* interpreter) {
@@ -532,7 +532,7 @@ static DART_NOINLINE bool InvokeRuntime(Thread* thread,
532532
RuntimeFunction drt,
533533
const NativeArguments& args) {
534534
InterpreterSetjmpBuffer buffer(interpreter);
535-
if (!setjmp(buffer.buffer_)) {
535+
if (!DART_SETJMP(buffer.buffer_)) {
536536
thread->set_vm_tag(reinterpret_cast<uword>(drt));
537537
drt(args);
538538
thread->set_vm_tag(VMTag::kDartInterpretedTagId);
@@ -581,7 +581,7 @@ DART_NOINLINE bool Interpreter::InvokeCompiled(Thread* thread,
581581
Exit(thread, *FP, call_top + 1, *pc);
582582
{
583583
InterpreterSetjmpBuffer buffer(this);
584-
if (!setjmp(buffer.buffer_)) {
584+
if (!DART_SETJMP(buffer.buffer_)) {
585585
#if defined(USING_SIMULATOR)
586586
// We need to beware that bouncing between the interpreter and the
587587
// simulator may exhaust the C stack before exhausting either the

0 commit comments

Comments
 (0)