Files
sdk/runtime/vm/stub_code.h
Ryan Macnak d36adbacaf [vm] Remove the VM isolate.
The former contents of the VM isolate are now included into each isolate group. This makes each isolate group's heap independent, and in particular allows each heap to be allocated to a separate pointer cage (not done in this CL).

The duplicated stubs that allowed PC relative calls are removed, since the originals can now be the target of PC relative calls.

The bootstrapping needing to load an AppJIT or AppAOT snapshot is reduced to allocating the oddballs. The code is entirely dropped in the AOT runtime, but the JIT runtime still has it to allow for flags to affect the compilation of the stub code. Further refactoring might be able to remove this for the JIT runtime too, with only gen_snapshot knowing how to bootstrap.

Class serialization no longer distinguishes predefined classes.

The page containing null is marked as never-evacuate. null, false and true must not move because the compiler relies on their low bits having certain patterns for some optimizations. (Previously, the entire VM isolate heap never moved.)

Compaction is disabled for IA32. Due to register pressure, some stub calls must not use a scratch register and embed the address of Code.

The page containing the call-through-safepoint stub is frozen when running with --write-protect-code and the stub is created at runtime (instead of loaded from an AppJIT or AppAOT snapshot). This stub must remain executable even during a safepoint, as a foreign call might during return during a safepoint and only block after the stub directs it to the runtime.

The snapshot symbols are renamed to kDartSnapshotData and kDartSnapshotText. There is no need to distinguish the VM isolate's snapshot, and snaphots are per isolate group not per isolate. Aliases with the old names are added to ease migration.

Some global flags that were automatically set based on the VM isolate's snapshot are now isolate group flags and automatically set by the isolate group's snapshot.

TEST=ci
Change-Id: Iee82016057d609112e9b021d178fc3d4d18b5044
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/500621
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Tess Strickland <sstrickl@google.com>
SLSA-Policy-Verified: SLSA Policy Verification Service <devtools-gerritcodereview-exitgate@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2026-05-18 11:35:03 -07:00

129 lines
4.1 KiB
C++

// Copyright (c) 2011, 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.
#ifndef RUNTIME_VM_STUB_CODE_H_
#define RUNTIME_VM_STUB_CODE_H_
#include <functional>
#include "vm/allocation.h"
#include "vm/compiler/runtime_api.h"
#include "vm/object.h"
#include "vm/stub_code_list.h"
#if !defined(DART_PRECOMPILED_RUNTIME)
#include "vm/compiler/assembler/assembler.h"
#include "vm/compiler/stub_code_compiler.h"
#endif // !defined(DART_PRECOMPILED_RUNTIME)
namespace dart {
// Forward declarations.
class Code;
class Isolate;
class ObjectPointerVisitor;
class Thread;
// Is it permitted for the stubs above to refer to Object::null(), which is
// allocated in the VM isolate and shared across all isolates.
// However, in cases where a simple GC-safe placeholder is needed on the stack,
// using Smi 0 instead of Object::null() is slightly more efficient, since a Smi
// does not require relocation.
// class StubCode is used to maintain the lifecycle of stubs.
class StubCode : public AllStatic {
public:
// Generate all stubs which are shared across all isolates, this is done
// only once and the stub code resides in the vm_isolate heap.
static void Init();
static void Cleanup();
// Check if specified pc is in the dart invocation stub used for
// transitioning into dart code.
static bool InInvocationStub(Thread* T,
uword pc,
bool is_interpreted_frame = false);
// Check if the specified pc is in the jump to frame stub.
static bool InJumpToFrameStub(Thread* T, uword pc);
// Returns nullptr if no stub found.
static const char* NameOfStub(uword entry_point);
// Callback is called for each stub until it returns false.
static void ForEachStub(
const std::function<bool(const char*, uword)>& callback);
static constexpr const char* StubNames[] = {
#define STUB_CODE_NAME(name) #name,
VM_STUB_CODE_LIST(STUB_CODE_NAME)
#undef STUB_CODE_NAME
};
// Define the shared stub code accessors.
#define STUB_CODE_ACCESSOR(name) \
static const Code& name() { return Roots::stub_handle(k##name##Index); }
VM_STUB_CODE_LIST(STUB_CODE_ACCESSOR);
#undef STUB_CODE_ACCESSOR
#if !defined(DART_PRECOMPILED_RUNTIME)
static const Code& SubtypeTestCacheStubForUsedInputs(intptr_t i) {
switch (i) {
case 1:
return StubCode::Subtype1TestCache();
case 2:
return StubCode::Subtype2TestCache();
case 3:
return StubCode::Subtype3TestCache();
case 4:
return StubCode::Subtype4TestCache();
case 6:
return StubCode::Subtype6TestCache();
case 7:
return StubCode::Subtype7TestCache();
default:
UNREACHABLE();
return StubCode::Subtype7TestCache();
}
}
static CodePtr GetAllocationStubForClass(const Class& cls);
static CodePtr GetAllocationStubForTypedData(classid_t class_id);
#endif // !defined(DART_PRECOMPILED_RUNTIME)
#if !defined(DART_PRECOMPILED_RUNTIME)
// Generate the stub and finalize the generated code into the stub
// code executable area.
static CodePtr Generate(const char* name,
compiler::ObjectPoolBuilder* object_pool_builder,
void (compiler::StubCodeCompiler::*GenerateStub)());
#endif // !defined(DART_PRECOMPILED_RUNTIME)
static const Code& UnoptimizedStaticCallEntry(intptr_t num_args_tested);
static const char* NameAt(intptr_t index) { return StubNames[index]; }
static const Code& EntryAt(intptr_t index) {
return Roots::stub_handle(index);
}
static void EntryAtPut(intptr_t index, CodePtr code) {
Roots::stub_handle(index).initRO(code);
}
static intptr_t NumEntries() { return kNumStubEntries; }
private:
friend class MegamorphicCacheTable;
enum {
#define STUB_CODE_ENTRY(name) k##name##Index,
VM_STUB_CODE_LIST(STUB_CODE_ENTRY)
#undef STUB_CODE_ENTRY
kNumStubEntries
};
};
} // namespace dart
#endif // RUNTIME_VM_STUB_CODE_H_