mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 15:57:17 +00:00
fb43937e20
During safepoint we can distinguish between * owner of the safepoint operation (which is running code) * everyone else (which are all blocked Currently `Thread::IsAtSafepoint()` will return true for both. Since the thread owning the safepoint operation is running, it's not actually guaranteed that it's at "safe" point (e.g. to GC or to deopt) - it really depends on what it's doing. => This CL will change it so that only actually parked threads will have `Thread::IsAtSafepoint()`. In order to do that we change varrious usages of `IsAtSafepoint()` to be more precise: * `Thread::OwnsSafepoint()`: True if this thread owns the active safepoint. The thread is running. * `Thread::OwnsGCSafepoint()`: True if the active safepoint is a GC (or Deopt) safepoint and this thread owns it. The thread is running. * `Thread::OwnsDeoptSafepoint()`: True if the active safepoint is a Deopt safepoint and this thread owns it. The thread is running. * `Thread::CanAcquireSafepointLocks()`: True if the thread is allowed to acquire safepoint locks. * `Thread::IsAtSafepoint()`: true if this thread is parked at a safepoint TEST=ci Change-Id: I1a5a6727e84843ae79e0a344c438da19b7d6d916 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/295781 Commit-Queue: Martin Kustermann <kustermann@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
109 lines
3.7 KiB
C++
109 lines
3.7 KiB
C++
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
#include "vm/ffi_callback_trampolines.h"
|
|
|
|
#if !defined(DART_PRECOMPILED_RUNTIME)
|
|
#include "vm/code_comments.h"
|
|
#include "vm/code_observers.h"
|
|
#include "vm/compiler/assembler/assembler.h"
|
|
#include "vm/compiler/assembler/disassembler.h"
|
|
#include "vm/exceptions.h"
|
|
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
|
|
|
namespace dart {
|
|
|
|
#if !defined(DART_PRECOMPILED_RUNTIME)
|
|
uword NativeCallbackTrampolines::TrampolineForId(int32_t callback_id) {
|
|
#if defined(DART_PRECOMPILER)
|
|
ASSERT(!Enabled());
|
|
UNREACHABLE();
|
|
#else
|
|
const intptr_t trampolines_per_page = NumCallbackTrampolinesPerPage();
|
|
const intptr_t page_index = callback_id / trampolines_per_page;
|
|
const uword entry_point = trampoline_pages_[page_index]->start();
|
|
|
|
return entry_point +
|
|
(callback_id % trampolines_per_page) *
|
|
compiler::StubCodeCompiler::kNativeCallbackTrampolineSize;
|
|
#endif
|
|
}
|
|
|
|
void NativeCallbackTrampolines::AllocateTrampoline() {
|
|
#if defined(DART_PRECOMPILER)
|
|
ASSERT(!Enabled());
|
|
UNREACHABLE();
|
|
#else
|
|
|
|
// Callback IDs are limited to 32-bits for trampoline compactness.
|
|
if (kWordSize == 8 &&
|
|
!Utils::IsInt(32, next_callback_id_ + NumCallbackTrampolinesPerPage())) {
|
|
Exceptions::ThrowOOM();
|
|
}
|
|
|
|
if (trampolines_left_on_page_ == 0) {
|
|
// Fuchsia requires memory to be allocated with ZX_RIGHT_EXECUTE in order
|
|
// to be flipped to kReadExecute after being kReadWrite.
|
|
VirtualMemory* const memory = VirtualMemory::AllocateAligned(
|
|
/*size=*/VirtualMemory::PageSize(),
|
|
/*alignment=*/VirtualMemory::PageSize(),
|
|
/*is_executable=*/true,
|
|
/*is_compressed=*/false,
|
|
/*name=*/"Dart VM FFI callback trampolines");
|
|
memory->Protect(VirtualMemory::kReadWrite);
|
|
|
|
if (memory == nullptr) {
|
|
Exceptions::ThrowOOM();
|
|
}
|
|
|
|
trampoline_pages_.Add(memory);
|
|
|
|
compiler::Assembler assembler(/*object_pool_builder=*/nullptr);
|
|
compiler::StubCodeCompiler stubCodeCompiler(&assembler);
|
|
stubCodeCompiler.GenerateJITCallbackTrampolines(next_callback_id_);
|
|
|
|
MemoryRegion region(memory->address(), memory->size());
|
|
assembler.FinalizeInstructions(region);
|
|
|
|
memory->Protect(VirtualMemory::kReadExecute);
|
|
|
|
#if !defined(PRODUCT)
|
|
const char* name = "FfiJitCallbackTrampolines";
|
|
ASSERT(!Thread::Current()->OwnsSafepoint());
|
|
if (CodeObservers::AreActive()) {
|
|
const auto& comments = CreateCommentsFrom(&assembler);
|
|
CodeObservers::NotifyAll(name,
|
|
/*base=*/memory->start(),
|
|
/*prologue_offset=*/0,
|
|
/*size=*/assembler.CodeSize(),
|
|
/*optimized=*/false, // not really relevant
|
|
&comments);
|
|
}
|
|
#endif
|
|
#if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
|
|
if (FLAG_disassemble_stubs && FLAG_support_disassembler) {
|
|
DisassembleToStdout formatter;
|
|
THR_Print(
|
|
"Code for native callback trampolines "
|
|
"[%" Pd " -> %" Pd "]: {\n",
|
|
next_callback_id_,
|
|
next_callback_id_ + NumCallbackTrampolinesPerPage() - 1);
|
|
const auto& comments = CreateCommentsFrom(&assembler);
|
|
Disassembler::Disassemble(memory->start(),
|
|
memory->start() + assembler.CodeSize(),
|
|
&formatter, &comments);
|
|
}
|
|
#endif
|
|
|
|
trampolines_left_on_page_ = NumCallbackTrampolinesPerPage();
|
|
}
|
|
|
|
trampolines_left_on_page_--;
|
|
next_callback_id_++;
|
|
#endif // defined(DART_PRECOMPILER)
|
|
}
|
|
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
|
|
|
} // namespace dart
|