mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 22:00:09 +00:00
85de9c1d7e
If we are generating a SubtypeTestCache for a known type that only needs instantiator type arguments to be fully instantiated, then don't store and check against the unneeded function type arguments. TEST=vm/cc/STC, vm/cc/TTS, ci Change-Id: I370adf820168079322b8a87811057670a47ee6b3 Cq-Include-Trybots: luci.dart.try:vm-tsan-linux-release-x64-try,vm-reload-rollback-linux-release-x64-try,vm-reload-linux-release-x64-try,vm-linux-release-x64-try,vm-aot-tsan-linux-release-x64-try,vm-aot-linux-release-x64-try,vm-aot-linux-product-x64-try,vm-aot-linux-debug-x64-try,vm-linux-debug-x64-try,vm-mac-debug-arm64-try,vm-aot-mac-release-arm64-try,vm-ffi-qemu-linux-release-arm-try,vm-ffi-qemu-linux-release-riscv64-try,vm-linux-debug-ia32-try,vm-linux-release-ia32-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/311382 Reviewed-by: Martin Kustermann <kustermann@google.com> Commit-Queue: Tess Strickland <sstrickl@google.com> Reviewed-by: Alexander Markov <alexmarkov@google.com>
159 lines
5.4 KiB
C++
159 lines
5.4 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 "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;
|
|
|
|
// 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();
|
|
|
|
// Returns true if stub code has been initialized.
|
|
static bool HasBeenInitialized() {
|
|
return initialized_.load(std::memory_order_acquire);
|
|
}
|
|
static void InitializationDone() {
|
|
initialized_.store(true, std::memory_order_release);
|
|
}
|
|
|
|
// Check if specified pc is in the dart invocation stub used for
|
|
// transitioning into dart code.
|
|
static bool InInvocationStub(uword pc);
|
|
|
|
// Check if the specified pc is in the jump to frame stub.
|
|
static bool InJumpToFrameStub(uword pc);
|
|
|
|
// Returns nullptr if no stub found.
|
|
static const char* NameOfStub(uword entry_point);
|
|
|
|
// Define the shared stub code accessors.
|
|
#define STUB_CODE_ACCESSOR(name) \
|
|
static const Code& name() { return *entries_[k##name##Index].code; } \
|
|
static intptr_t name##Size() { return name().Size(); }
|
|
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(TARGET_ARCH_IA32)
|
|
static CodePtr GetBuildGenericMethodExtractorStub(
|
|
compiler::ObjectPoolBuilder* pool) {
|
|
return GetBuildMethodExtractorStub(pool, /*generic=*/true);
|
|
}
|
|
static CodePtr GetBuildNonGenericMethodExtractorStub(
|
|
compiler::ObjectPoolBuilder* pool) {
|
|
return GetBuildMethodExtractorStub(pool, /*generic=*/false);
|
|
}
|
|
#endif
|
|
|
|
#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 entries_[index].name; }
|
|
|
|
static const Code& EntryAt(intptr_t index) { return *(entries_[index].code); }
|
|
static void EntryAtPut(intptr_t index, Code* entry) {
|
|
DEBUG_ASSERT(entry->IsReadOnlyHandle());
|
|
ASSERT(entries_[index].code == nullptr);
|
|
entries_[index].code = entry;
|
|
}
|
|
static intptr_t NumEntries() { return kNumStubEntries; }
|
|
|
|
#if !defined(DART_PRECOMPILED_RUNTIME)
|
|
#define GENERATE_STUB(name) \
|
|
static CodePtr BuildIsolateSpecific##name##Stub( \
|
|
compiler::ObjectPoolBuilder* opw) { \
|
|
return StubCode::Generate( \
|
|
"_iso_stub_" #name, opw, \
|
|
&compiler::StubCodeCompiler::Generate##name##Stub); \
|
|
}
|
|
VM_STUB_CODE_LIST(GENERATE_STUB);
|
|
#undef GENERATE_STUB
|
|
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
|
|
|
private:
|
|
friend class MegamorphicCacheTable;
|
|
|
|
static CodePtr GetBuildMethodExtractorStub(compiler::ObjectPoolBuilder* pool,
|
|
bool generic);
|
|
|
|
enum {
|
|
#define STUB_CODE_ENTRY(name) k##name##Index,
|
|
VM_STUB_CODE_LIST(STUB_CODE_ENTRY)
|
|
#undef STUB_CODE_ENTRY
|
|
kNumStubEntries
|
|
};
|
|
|
|
struct StubCodeEntry {
|
|
Code* code;
|
|
const char* name;
|
|
#if !defined(DART_PRECOMPILED_RUNTIME)
|
|
void (compiler::StubCodeCompiler::*generator)();
|
|
#endif
|
|
};
|
|
static StubCodeEntry entries_[kNumStubEntries];
|
|
static AcqRelAtomic<bool> initialized_;
|
|
};
|
|
|
|
} // namespace dart
|
|
|
|
#endif // RUNTIME_VM_STUB_CODE_H_
|