27760001f5
* Introduce forward declaration for RawObject; * Move compiler::target::ClassTable::ClassOffsetFor under ifdef PRODUCT Change-Id: Iacf5cbdaec0c2999aae7c8e0683a58e392f3e960 Reviewed-on: https://dart-review.googlesource.com/c/91220 Commit-Queue: Vyacheslav Egorov <vegorov@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com> Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
351 lines
11 KiB
C++
351 lines
11 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.
|
|
|
|
#ifndef RUNTIME_VM_COMPILER_RUNTIME_API_H_
|
|
#define RUNTIME_VM_COMPILER_RUNTIME_API_H_
|
|
|
|
// This header defines the API that compiler can use to interact with the
|
|
// underlying Dart runtime that it is embedded into.
|
|
//
|
|
// Compiler is not allowed to directly interact with any objects - it can only
|
|
// use classes like dart::Object, dart::Code, dart::Function and similar as
|
|
// opaque handles. All interactions should be done through helper methods
|
|
// provided by this header.
|
|
//
|
|
// This header also provides ways to get word sizes, frame layout, field
|
|
// offsets for the target runtime. Note that these can be different from
|
|
// those on the host. Helpers providing access to these values live
|
|
// in compiler::target namespace.
|
|
|
|
#include "platform/globals.h"
|
|
#include "vm/allocation.h"
|
|
#include "vm/bitfield.h"
|
|
#include "vm/code_entry_kind.h"
|
|
#include "vm/frame_layout.h"
|
|
#include "vm/pointer_tagging.h"
|
|
|
|
namespace dart {
|
|
|
|
// Forward declarations.
|
|
class Class;
|
|
class Code;
|
|
class Function;
|
|
class LocalVariable;
|
|
class Object;
|
|
class String;
|
|
class Zone;
|
|
namespace compiler {
|
|
class Assembler;
|
|
}
|
|
|
|
namespace compiler {
|
|
|
|
// Host word sizes.
|
|
//
|
|
// Code in the compiler namespace should not use kWordSize and derived
|
|
// constants directly because the word size on host and target might
|
|
// be different.
|
|
//
|
|
// To prevent this we introduce variables that would shadow these
|
|
// constants and introduce compilation errors when used.
|
|
//
|
|
// target::kWordSize and target::ObjectAlignment give access to
|
|
// word size and object aligment offsets for the target.
|
|
//
|
|
// Similarly kHostWordSize gives access to the host word size.
|
|
class InvalidClass {};
|
|
extern InvalidClass kWordSize;
|
|
extern InvalidClass kWordSizeLog2;
|
|
extern InvalidClass kNewObjectAlignmentOffset;
|
|
extern InvalidClass kOldObjectAlignmentOffset;
|
|
extern InvalidClass kNewObjectBitPosition;
|
|
extern InvalidClass kObjectAlignment;
|
|
extern InvalidClass kObjectAlignmentLog2;
|
|
extern InvalidClass kObjectAlignmentMask;
|
|
|
|
static constexpr intptr_t kHostWordSize = dart::kWordSize;
|
|
static constexpr intptr_t kHostWordSizeLog2 = dart::kWordSizeLog2;
|
|
|
|
//
|
|
// Object handles.
|
|
//
|
|
|
|
// Create an empty handle.
|
|
Object& NewZoneHandle(Zone* zone);
|
|
|
|
// Clone the given handle.
|
|
Object& NewZoneHandle(Zone* zone, const Object&);
|
|
|
|
// Returns true if [a] and [b] are the same object.
|
|
bool IsSameObject(const Object& a, const Object& b);
|
|
|
|
// Returns true if the given handle is a zone handle or one of the global
|
|
// cached handles.
|
|
bool IsNotTemporaryScopedHandle(const Object& obj);
|
|
|
|
// Returns true if [obj] resides in old space.
|
|
bool IsInOldSpace(const Object& obj);
|
|
|
|
// Returns true if [obj] is not a Field/ICData clone.
|
|
//
|
|
// Used to assert that we are not embedding pointers to cloned objects that are
|
|
// used by background compiler into object pools / code.
|
|
bool IsOriginalObject(const Object& object);
|
|
|
|
// Clear the given handle.
|
|
void SetToNull(Object* obj);
|
|
|
|
// Helper functions to upcast handles.
|
|
//
|
|
// Note: compiler code cannot include object.h so it cannot see that Object is
|
|
// a superclass of Code or Function - thus we have to cast these pointers using
|
|
// reinterpret_cast.
|
|
inline const Object& ToObject(const Code& handle) {
|
|
return *reinterpret_cast<const Object*>(&handle);
|
|
}
|
|
|
|
inline const Object& ToObject(const Function& handle) {
|
|
return *reinterpret_cast<const Object*>(&handle);
|
|
}
|
|
|
|
// Returns some hash value for the given object.
|
|
//
|
|
// Note: the given hash value does not necessarily match Object.get:hashCode,
|
|
// or canonical hash.
|
|
intptr_t ObjectHash(const Object& obj);
|
|
|
|
// If the given object represents a Dart integer returns true and sets [value]
|
|
// to the value of the integer.
|
|
bool HasIntegerValue(const dart::Object& obj, int64_t* value);
|
|
|
|
// Creates a random cookie to be used for masking constants embedded in the
|
|
// generated code.
|
|
int32_t CreateJitCookie();
|
|
|
|
class RuntimeEntry : public ValueObject {
|
|
public:
|
|
virtual ~RuntimeEntry() {}
|
|
virtual void Call(compiler::Assembler* assembler,
|
|
intptr_t argument_count) const = 0;
|
|
};
|
|
|
|
// Allocate a string object with the given content in the runtime heap.
|
|
const String& AllocateString(const char* buffer);
|
|
|
|
DART_NORETURN void BailoutWithBranchOffsetError();
|
|
|
|
// compiler::target namespace contains information about the target platform:
|
|
//
|
|
// - word sizes and derived constants
|
|
// - offsets of fields
|
|
// - sizes of structures
|
|
namespace target {
|
|
|
|
// Currently we define target::word to match dart::word which represents
|
|
// host word.
|
|
//
|
|
// Once refactoring of the compiler is complete we will switch target::word
|
|
// to be independent from host word.
|
|
typedef dart::word word;
|
|
typedef dart::uword uword;
|
|
|
|
static constexpr word kWordSize = dart::kWordSize;
|
|
static constexpr word kWordSizeLog2 = dart::kWordSizeLog2;
|
|
static_assert((1 << kWordSizeLog2) == kWordSize,
|
|
"kWordSizeLog2 should match kWordSize");
|
|
|
|
using ObjectAlignment = dart::ObjectAlignment<kWordSize, kWordSizeLog2>;
|
|
|
|
// Information about frame_layout that compiler should be targeting.
|
|
extern FrameLayout frame_layout;
|
|
|
|
// Returns the FP-relative index where [variable] can be found (assumes
|
|
// [variable] is not captured), in bytes.
|
|
inline int FrameOffsetInBytesForVariable(const LocalVariable* variable) {
|
|
return frame_layout.FrameSlotForVariable(variable) * kWordSize;
|
|
}
|
|
|
|
// Encode tag word for a heap allocated object with the given class id and
|
|
// size.
|
|
//
|
|
// Note: even on 64-bit platforms we only use lower 32-bits of the tag word.
|
|
uint32_t MakeTagWordForNewSpaceObject(classid_t cid, uword instance_size);
|
|
|
|
//
|
|
// Target specific information about objects.
|
|
//
|
|
|
|
// Returns true if the given object can be represented as a Smi on the
|
|
// target platform.
|
|
bool IsSmi(const dart::Object& a);
|
|
|
|
// Return raw Smi representation of the given object for the target platform.
|
|
word ToRawSmi(const dart::Object& a);
|
|
|
|
// Return raw Smi representation of the given integer value for the target
|
|
// platform.
|
|
//
|
|
// Note: method assumes that caller has validated that value is representable
|
|
// as a Smi.
|
|
word ToRawSmi(intptr_t value);
|
|
|
|
// If the given object can be loaded from the thread on the target then
|
|
// return true and set offset (if provided) to the offset from the
|
|
// thread pointer to a field that contains the object.
|
|
bool CanLoadFromThread(const dart::Object& object, word* offset = nullptr);
|
|
|
|
// On IA32 we can embed raw pointers into generated code.
|
|
#if defined(TARGET_ARCH_IA32)
|
|
// Returns true if the pointer to the given object can be directly embedded
|
|
// into the generated code (because the object is immortal and immovable).
|
|
bool CanEmbedAsRawPointerInGeneratedCode(const dart::Object& obj);
|
|
|
|
// Returns raw pointer value for the given object. Should only be invoked
|
|
// if CanEmbedAsRawPointerInGeneratedCode returns true.
|
|
word ToRawPointer(const dart::Object& a);
|
|
#endif // defined(TARGET_ARCH_IA32)
|
|
|
|
//
|
|
// Target specific offsets and constants.
|
|
//
|
|
// Currently we use the same names for classes, constants and getters to make
|
|
// migration easier.
|
|
|
|
class RawObject : public AllStatic {
|
|
public:
|
|
static const word kClassIdTagPos;
|
|
static const word kClassIdTagSize;
|
|
static const word kBarrierOverlapShift;
|
|
};
|
|
|
|
class Object : public AllStatic {
|
|
public:
|
|
// Offset of the tags word.
|
|
static word tags_offset();
|
|
};
|
|
|
|
class ObjectPool : public AllStatic {
|
|
public:
|
|
// Return offset to the element with the given [index] in the object pool.
|
|
static intptr_t element_offset(intptr_t index);
|
|
};
|
|
|
|
class Class : public AllStatic {
|
|
public:
|
|
// Return class id of the given class on the target.
|
|
static classid_t GetId(const dart::Class& handle);
|
|
|
|
// Return instance size for the given class on the target.
|
|
static uword GetInstanceSize(const dart::Class& handle);
|
|
};
|
|
|
|
class Instance : public AllStatic {
|
|
public:
|
|
static word DataOffsetFor(intptr_t cid);
|
|
};
|
|
|
|
class Double : public AllStatic {
|
|
public:
|
|
static word value_offset();
|
|
};
|
|
|
|
class Float32x4 : public AllStatic {
|
|
public:
|
|
static word value_offset();
|
|
};
|
|
|
|
class Float64x2 : public AllStatic {
|
|
public:
|
|
static word value_offset();
|
|
};
|
|
|
|
class Thread : public AllStatic {
|
|
public:
|
|
static word top_offset();
|
|
static word end_offset();
|
|
static word isolate_offset();
|
|
static word call_to_runtime_entry_point_offset();
|
|
static word null_error_shared_with_fpu_regs_entry_point_offset();
|
|
static word null_error_shared_without_fpu_regs_entry_point_offset();
|
|
static word write_barrier_mask_offset();
|
|
static word monomorphic_miss_entry_offset();
|
|
static word write_barrier_wrappers_thread_offset(intptr_t regno);
|
|
static word array_write_barrier_entry_point_offset();
|
|
static word write_barrier_entry_point_offset();
|
|
static word vm_tag_offset();
|
|
|
|
#define THREAD_XMM_CONSTANT_LIST(V) \
|
|
V(float_not) \
|
|
V(float_negate) \
|
|
V(float_absolute) \
|
|
V(float_zerow) \
|
|
V(double_negate) \
|
|
V(double_abs)
|
|
|
|
#define DECLARE_CONSTANT_OFFSET_GETTER(name) \
|
|
static word name##_address_offset();
|
|
THREAD_XMM_CONSTANT_LIST(DECLARE_CONSTANT_OFFSET_GETTER)
|
|
#undef DECLARE_CONSTANT_OFFSET_GETTER
|
|
};
|
|
|
|
class Isolate : public AllStatic {
|
|
public:
|
|
static word class_table_offset();
|
|
};
|
|
|
|
class ClassTable : public AllStatic {
|
|
public:
|
|
static word table_offset();
|
|
#if !defined(PRODUCT)
|
|
static word ClassOffsetFor(intptr_t cid);
|
|
static word StateOffsetFor(intptr_t cid);
|
|
static word TableOffsetFor(intptr_t cid);
|
|
static word CounterOffsetFor(intptr_t cid, bool is_new);
|
|
static word SizeOffsetFor(intptr_t cid, bool is_new);
|
|
#endif // !defined(PRODUCT)
|
|
static const word kSizeOfClassPairLog2;
|
|
};
|
|
|
|
#if !defined(PRODUCT)
|
|
class ClassHeapStats : public AllStatic {
|
|
public:
|
|
static word TraceAllocationMask();
|
|
static word state_offset();
|
|
static word allocated_since_gc_new_space_offset();
|
|
static word allocated_size_since_gc_new_space_offset();
|
|
};
|
|
#endif // !defined(PRODUCT)
|
|
|
|
class Instructions : public AllStatic {
|
|
public:
|
|
static const intptr_t kPolymorphicEntryOffset;
|
|
static const intptr_t kMonomorphicEntryOffset;
|
|
static intptr_t HeaderSize();
|
|
};
|
|
|
|
class Code : public AllStatic {
|
|
public:
|
|
#if defined(TARGET_ARCH_IA32)
|
|
static uword EntryPointOf(const dart::Code& code);
|
|
#endif // defined(TARGET_ARCH_IA32)
|
|
|
|
static intptr_t object_pool_offset();
|
|
static intptr_t entry_point_offset(
|
|
CodeEntryKind kind = CodeEntryKind::kNormal);
|
|
static intptr_t saved_instructions_offset();
|
|
};
|
|
|
|
class Heap : public AllStatic {
|
|
public:
|
|
// Return true if an object with the given instance size is allocatable
|
|
// in new space on the target.
|
|
static bool IsAllocatableInNewSpace(intptr_t instance_size);
|
|
};
|
|
|
|
} // namespace target
|
|
} // namespace compiler
|
|
} // namespace dart
|
|
|
|
#endif // RUNTIME_VM_COMPILER_RUNTIME_API_H_
|