mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
Reland "[vm] Create offsets_extractor tool."
This reverts commit224f82c21c
. Reason for revert: Just need to split DBC section into 32 and 64 bit Original change's description: > Revert "[vm] Create offsets_extractor tool." > > This reverts commit3015d79371
. > > Reason for revert: Fails the Flutter build > /b/s/w/ir/cache/builder/mac_sdk -mmacosx-version-min=10.12 -m32 -fno-strict-aliasing -fstack-protector-all -fcolor-diagnostics -Wall -Wextra -Wendif-labels -Werror -Wno-missing-field-initializers -Wno-unused-parameter -Wunguarded-availability -fvisibility=hidden -stdlib=libc++ -Wheader-hygiene -Wstring-conversion -Wthread-safety -O2 -fno-ident -fdata-sections -ffunction-sections -g2 -Werror -Wall -Wextra -Wno-unused-parameter -Wno-unused-private-field -Wnon-virtual-dtor -Wvla -Wno-conversion-null -Woverloaded-virtual -Wno-comments -g3 -ggdb3 -fno-rtti -fno-exceptions -Wimplicit-fallthrough -O3 -fvisibility-inlines-hidden -std=c++14 -fno-rtti -fno-exceptions -c ../../third_party/dart/runtime/vm/dart.cc -o clang_x86/obj/third_party/dart/runtime/vm/libdart_vm_nosnapshot_with_precompiler.dart.o > In file included from ../../third_party/dart/runtime/vm/dart.cc:9: > ../../third_party/dart/runtime/vm/compiler/runtime_offsets_extracted.h:958:50: error: implicit conversion from 'long long' to 'const dart::word' (aka 'const long') changes value from 576460752303423487 to -1 [-Werror,-Wconstant-conversion] > static constexpr dart::word Array_kMaxElements = 576460752303423487; > ~~~~~~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~ > ../../third_party/dart/runtime/vm/compiler/runtime_offsets_extracted.h:965:51: error: implicit conversion from 'long long' to 'const dart::word' (aka 'const long') changes value from 2305843009213693951 to -1 [-Werror,-Wconstant-conversion] > static constexpr dart::word String_kMaxElements = 2305843009213693951; > ~~~~~~~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~ > 2 errors generated. > > Change-Id: Iaf509c6ee7a2ce75664935519ac02a933a9eb2bf > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/104402 > Reviewed-by: Siva Annamalai <asiva@google.com> > Commit-Queue: Siva Annamalai <asiva@google.com> > Auto-Submit: Siva Annamalai <asiva@google.com> TBR=asiva@google.com Change-Id: Ibf749ceee274b03cdffa6d7ed46fcbe75d1a1e94 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/104620 Reviewed-by: Liam Appelbe <liama@google.com> Reviewed-by: Siva Annamalai <asiva@google.com> Commit-Queue: Liam Appelbe <liama@google.com>
This commit is contained in:
parent
0241e40c15
commit
5b72293f49
|
@ -177,3 +177,15 @@ group("kernel_platform_files") {
|
|||
":vm_platform_stripped",
|
||||
]
|
||||
}
|
||||
|
||||
executable("offsets_extractor") {
|
||||
configs += [
|
||||
"..:dart_arch_config",
|
||||
"..:dart_config",
|
||||
":libdart_vm_config",
|
||||
]
|
||||
sources = [
|
||||
"compiler/offsets_extractor.cc",
|
||||
]
|
||||
include_dirs = [ ".." ]
|
||||
}
|
||||
|
|
|
@ -39,14 +39,6 @@ class ClassAndSize {
|
|||
friend class IsolateReloadContext; // For VisitObjectPointers.
|
||||
};
|
||||
|
||||
#if defined(ARCH_IS_32_BIT)
|
||||
const int kSizeOfClassPairLog2 = 3;
|
||||
#else
|
||||
const int kSizeOfClassPairLog2 = 4;
|
||||
#endif
|
||||
|
||||
COMPILE_ASSERT((1 << kSizeOfClassPairLog2) == sizeof(ClassAndSize));
|
||||
|
||||
#ifndef PRODUCT
|
||||
template <typename T>
|
||||
class AllocStats {
|
||||
|
@ -260,6 +252,24 @@ class ClassTable {
|
|||
// Used by the generated code.
|
||||
static intptr_t ClassOffsetFor(intptr_t cid);
|
||||
|
||||
#ifndef PRODUCT
|
||||
// Describes layout of heap stats for code generation. See offset_extractor.cc
|
||||
struct ArrayLayout {
|
||||
static intptr_t elements_start_offset() { return 0; }
|
||||
|
||||
static constexpr intptr_t kElementSize = sizeof(ClassHeapStats);
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(ARCH_IS_32_BIT)
|
||||
static constexpr int kSizeOfClassPairLog2 = 3;
|
||||
#else
|
||||
static constexpr int kSizeOfClassPairLog2 = 4;
|
||||
#endif
|
||||
static_assert(
|
||||
(1 << kSizeOfClassPairLog2) == sizeof(ClassAndSize),
|
||||
"Mismatch between sizeof(ClassAndSize) and kSizeOfClassPairLog2");
|
||||
|
||||
#ifndef PRODUCT
|
||||
// Called whenever a class is allocated in the runtime.
|
||||
void UpdateAllocatedNew(intptr_t cid, intptr_t size) {
|
||||
|
@ -285,6 +295,11 @@ class ClassTable {
|
|||
// Called immediately after a new GC.
|
||||
void UpdatePromoted();
|
||||
|
||||
// Used by the generated code.
|
||||
static intptr_t class_heap_stats_table_offset() {
|
||||
return OFFSET_OF(ClassTable, class_heap_stats_table_);
|
||||
}
|
||||
|
||||
// Used by the generated code.
|
||||
static intptr_t TableOffsetFor(intptr_t cid);
|
||||
|
||||
|
|
103
runtime/vm/compiler/offsets_extractor.cc
Normal file
103
runtime/vm/compiler/offsets_extractor.cc
Normal file
|
@ -0,0 +1,103 @@
|
|||
// 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 <iostream>
|
||||
|
||||
#include "vm/compiler/runtime_api.h"
|
||||
#include "vm/compiler/runtime_offsets_list.h"
|
||||
#include "vm/dart_entry.h"
|
||||
#include "vm/longjump.h"
|
||||
#include "vm/native_arguments.h"
|
||||
#include "vm/native_entry.h"
|
||||
#include "vm/object.h"
|
||||
#include "vm/object_store.h"
|
||||
#include "vm/runtime_entry.h"
|
||||
#include "vm/symbols.h"
|
||||
#include "vm/timeline.h"
|
||||
|
||||
#if defined(TARGET_ARCH_ARM)
|
||||
#define ARCH_DEF "defined(TARGET_ARCH_ARM)"
|
||||
#elif defined(TARGET_ARCH_X64)
|
||||
#define ARCH_DEF "defined(TARGET_ARCH_X64)"
|
||||
#elif defined(TARGET_ARCH_IA32)
|
||||
#define ARCH_DEF "defined(TARGET_ARCH_IA32)"
|
||||
#elif defined(TARGET_ARCH_ARM64)
|
||||
#define ARCH_DEF "defined(TARGET_ARCH_ARM64)"
|
||||
#elif defined(TARGET_ARCH_DBC) && defined(TARGET_ARCH_IS_32_BIT)
|
||||
#define ARCH_DEF "defined(TARGET_ARCH_DBC) && defined(TARGET_ARCH_IS_32_BIT)"
|
||||
#elif defined(TARGET_ARCH_DBC) && defined(TARGET_ARCH_IS_64_BIT)
|
||||
#define ARCH_DEF "defined(TARGET_ARCH_DBC) && defined(TARGET_ARCH_IS_64_BIT)"
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
|
||||
namespace dart {
|
||||
|
||||
void Assert::Fail(const char* format, ...) {
|
||||
abort();
|
||||
}
|
||||
|
||||
class OffsetsExtractor : public AllStatic {
|
||||
public:
|
||||
static void DumpOffsets() {
|
||||
#define PRINT_FIELD_OFFSET(Class, Name) \
|
||||
std::cout << "static constexpr dart::word " #Class "_" #Name " = " \
|
||||
<< Class::Name() << ";\n";
|
||||
|
||||
#define PRINT_ARRAY_LAYOUT(Class, Name) \
|
||||
std::cout << "static constexpr dart::word " #Class \
|
||||
"_elements_start_offset = " \
|
||||
<< Class::ArrayLayout::elements_start_offset() << ";\n"; \
|
||||
std::cout << "static constexpr dart::word " #Class "_element_size = " \
|
||||
<< Class::ArrayLayout::kElementSize << ";\n";
|
||||
|
||||
#define PRINT_ARRAY_STRUCTFIELD_OFFSET(Class, Name, ElementOffsetName, \
|
||||
FieldOffset)
|
||||
|
||||
#define PRINT_SIZEOF(Class, Name, What) \
|
||||
std::cout << "static constexpr dart::word " #Class "_" #Name " = " \
|
||||
<< sizeof(What) << ";\n";
|
||||
|
||||
#define PRINT_RANGE(Class, Name, Type, First, Last, Filter) \
|
||||
{ \
|
||||
auto filter = Filter; \
|
||||
bool comma = false; \
|
||||
std::cout << "static dart::word " #Class "_" #Name "[] = {"; \
|
||||
for (intptr_t i = static_cast<intptr_t>(First); \
|
||||
i <= static_cast<intptr_t>(Last); i++) { \
|
||||
auto v = static_cast<Type>(i); \
|
||||
std::cout << (comma ? ", " : "") << (filter(v) ? Class::Name(v) : -1); \
|
||||
comma = true; \
|
||||
} \
|
||||
std::cout << "};\n"; \
|
||||
}
|
||||
|
||||
#define PRINT_CONSTANT(Class, Name) \
|
||||
std::cout << "static constexpr dart::word " #Class "_" #Name " = " \
|
||||
<< Class::Name << ";\n";
|
||||
|
||||
#define PRECOMP_NO_CHECK(Code) Code
|
||||
|
||||
OFFSETS_LIST(PRINT_FIELD_OFFSET, PRINT_ARRAY_LAYOUT,
|
||||
PRINT_ARRAY_STRUCTFIELD_OFFSET, PRINT_SIZEOF, PRINT_RANGE,
|
||||
PRINT_CONSTANT, PRECOMP_NO_CHECK)
|
||||
|
||||
#undef PRINT_FIELD_OFFSET
|
||||
#undef PRINT_ARRAY_LAYOUT
|
||||
#undef PRINT_ARRAY_STRUCTFIELD_OFFSET
|
||||
#undef PRINT_SIZEOF
|
||||
#undef PRINT_RANGE
|
||||
#undef PRINT_CONSTANT
|
||||
#undef PRECOMP_NO_CHECK
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dart
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
std::cout << "#if " << ARCH_DEF << std::endl;
|
||||
dart::OffsetsExtractor::DumpOffsets();
|
||||
std::cout << "#endif // " << ARCH_DEF << std::endl;
|
||||
return 0;
|
||||
}
|
|
@ -728,7 +728,8 @@ word ClassTable::SizeOffsetFor(intptr_t cid, bool is_new) {
|
|||
}
|
||||
#endif // !defined(PRODUCT)
|
||||
|
||||
const word ClassTable::kSizeOfClassPairLog2 = dart::kSizeOfClassPairLog2;
|
||||
const word ClassTable::kSizeOfClassPairLog2 =
|
||||
dart::ClassTable::kSizeOfClassPairLog2;
|
||||
|
||||
const intptr_t Instructions::kPolymorphicEntryOffset =
|
||||
dart::Instructions::kPolymorphicEntryOffset;
|
||||
|
|
1343
runtime/vm/compiler/runtime_offsets_extracted.h
Normal file
1343
runtime/vm/compiler/runtime_offsets_extracted.h
Normal file
File diff suppressed because it is too large
Load diff
267
runtime/vm/compiler/runtime_offsets_list.h
Normal file
267
runtime/vm/compiler/runtime_offsets_list.h
Normal file
|
@ -0,0 +1,267 @@
|
|||
// 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_OFFSETS_LIST_H_
|
||||
#define RUNTIME_VM_COMPILER_RUNTIME_OFFSETS_LIST_H_
|
||||
|
||||
// Macro list of all constants that differ based on whether the architecture is
|
||||
// 32-bit or 64-bit. They are used to allow the target architecture to differ
|
||||
// from the host, like this:
|
||||
// 1) The macros correspond to constants defined throughout the VM that are
|
||||
// sized based on the *host* architecture.
|
||||
// 2) offsets_extractor.cc prints these values to runtime_offsets_extracted.h,
|
||||
// for both 32 and 64 bit architectures.
|
||||
// 3) runtime_api.h presents the runtime_offsets_extracted.h constants in a way
|
||||
// designed to look like the original constants from 1), but now namespaced
|
||||
// to dart::compiler::target, and sized based on the *target* architecture.
|
||||
// 4) Users of the constants from 1) can now just add the namespace from 3) to
|
||||
// get all their constants sized based on the target rather than the host.
|
||||
|
||||
// FIELD(Class, Name) Offset of a field within a class.
|
||||
// ARRAY(Class, Name) Offset of the first element and the size of the elements
|
||||
// in an array of this class.
|
||||
// ARRAY_STRUCTFIELD(Class, Name, Element, Field) Offset of a field within a
|
||||
// struct in an array of that struct, relative to the start of the array.
|
||||
// SIZEOF(Class, Name, What) Size of an object.
|
||||
// RANGE(Class, Name, Type, First, Last, Filter) An array of offsets generated
|
||||
// by passing a value of the given Type in the range from First to Last to
|
||||
// Class::Name() if Filter returns true for that value.
|
||||
// CONSTANT(Class, Name) Miscellaneous constant.
|
||||
// PRECOMP_NO_CHECK(Code) Don't check this offset in the precompiled runtime.
|
||||
#define OFFSETS_LIST(FIELD, ARRAY, ARRAY_STRUCTFIELD, SIZEOF, RANGE, CONSTANT, \
|
||||
PRECOMP_NO_CHECK) \
|
||||
ARRAY(ObjectPool, element_offset) \
|
||||
CONSTANT(Array, kMaxElements) \
|
||||
CONSTANT(Array, kMaxNewSpaceElements) \
|
||||
CONSTANT(ClassTable, kSizeOfClassPairLog2) \
|
||||
CONSTANT(Instructions, kMonomorphicEntryOffset) \
|
||||
CONSTANT(Instructions, kPolymorphicEntryOffset) \
|
||||
CONSTANT(HeapPage, kBytesPerCardLog2) \
|
||||
CONSTANT(NativeEntry, kNumCallWrapperArguments) \
|
||||
CONSTANT(String, kMaxElements) \
|
||||
CONSTANT(SubtypeTestCache, kFunctionTypeArguments) \
|
||||
CONSTANT(SubtypeTestCache, kInstanceClassIdOrFunction) \
|
||||
CONSTANT(SubtypeTestCache, kInstanceDelayedFunctionTypeArguments) \
|
||||
CONSTANT(SubtypeTestCache, kInstanceParentFunctionTypeArguments) \
|
||||
CONSTANT(SubtypeTestCache, kInstanceTypeArguments) \
|
||||
CONSTANT(SubtypeTestCache, kInstantiatorTypeArguments) \
|
||||
CONSTANT(SubtypeTestCache, kTestEntryLength) \
|
||||
CONSTANT(SubtypeTestCache, kTestResult) \
|
||||
FIELD(AbstractType, type_test_stub_entry_point_offset) \
|
||||
FIELD(ArgumentsDescriptor, count_offset) \
|
||||
FIELD(ArgumentsDescriptor, first_named_entry_offset) \
|
||||
FIELD(ArgumentsDescriptor, named_entry_size) \
|
||||
FIELD(ArgumentsDescriptor, name_offset) \
|
||||
FIELD(ArgumentsDescriptor, position_offset) \
|
||||
FIELD(ArgumentsDescriptor, positional_count_offset) \
|
||||
FIELD(ArgumentsDescriptor, type_args_len_offset) \
|
||||
FIELD(Array, data_offset) \
|
||||
FIELD(Array, length_offset) \
|
||||
FIELD(Array, tags_offset) \
|
||||
FIELD(Array, type_arguments_offset) \
|
||||
FIELD(Class, declaration_type_offset) \
|
||||
FIELD(Class, num_type_arguments_offset) \
|
||||
FIELD(Class, super_type_offset) \
|
||||
FIELD(Class, type_arguments_field_offset_in_words_offset) \
|
||||
NOT_IN_PRODUCT(FIELD(ClassHeapStats, TraceAllocationMask)) \
|
||||
NOT_IN_PRODUCT(FIELD(ClassHeapStats, allocated_since_gc_new_space_offset)) \
|
||||
NOT_IN_PRODUCT( \
|
||||
FIELD(ClassHeapStats, allocated_size_since_gc_new_space_offset)) \
|
||||
NOT_IN_PRODUCT(FIELD(ClassHeapStats, state_offset)) \
|
||||
FIELD(ClassTable, table_offset) \
|
||||
FIELD(Closure, context_offset) \
|
||||
FIELD(Closure, delayed_type_arguments_offset) \
|
||||
FIELD(Closure, function_offset) \
|
||||
FIELD(Closure, function_type_arguments_offset) \
|
||||
FIELD(Closure, hash_offset) \
|
||||
FIELD(Closure, instantiator_type_arguments_offset) \
|
||||
FIELD(Code, object_pool_offset) \
|
||||
FIELD(Code, saved_instructions_offset) \
|
||||
FIELD(Code, owner_offset) \
|
||||
FIELD(Context, num_variables_offset) \
|
||||
FIELD(Context, parent_offset) \
|
||||
FIELD(Double, value_offset) \
|
||||
FIELD(ExternalOneByteString, external_data_offset) \
|
||||
FIELD(ExternalTwoByteString, external_data_offset) \
|
||||
FIELD(Float32x4, value_offset) \
|
||||
FIELD(Float64x2, value_offset) \
|
||||
PRECOMP_NO_CHECK(FIELD(Field, guarded_cid_offset)) \
|
||||
PRECOMP_NO_CHECK(FIELD(Field, guarded_list_length_in_object_offset_offset)) \
|
||||
PRECOMP_NO_CHECK(FIELD(Field, guarded_list_length_offset)) \
|
||||
PRECOMP_NO_CHECK(FIELD(Field, is_nullable_offset)) \
|
||||
FIELD(Field, static_value_offset) \
|
||||
PRECOMP_NO_CHECK(FIELD(Field, kind_bits_offset)) \
|
||||
FIELD(Function, code_offset) \
|
||||
FIELD(Function, entry_point_offset) \
|
||||
FIELD(Function, unchecked_entry_point_offset) \
|
||||
PRECOMP_NO_CHECK(FIELD(Function, usage_counter_offset)) \
|
||||
FIELD(GrowableObjectArray, data_offset) \
|
||||
FIELD(GrowableObjectArray, length_offset) \
|
||||
FIELD(GrowableObjectArray, type_arguments_offset) \
|
||||
FIELD(HeapPage, card_table_offset) \
|
||||
FIELD(ICData, NumArgsTestedMask) \
|
||||
FIELD(ICData, NumArgsTestedShift) \
|
||||
FIELD(ICData, arguments_descriptor_offset) \
|
||||
FIELD(ICData, entries_offset) \
|
||||
PRECOMP_NO_CHECK(FIELD(ICData, owner_offset)) \
|
||||
PRECOMP_NO_CHECK(FIELD(ICData, state_bits_offset)) \
|
||||
NOT_IN_PRECOMPILED_RUNTIME(FIELD(ICData, receivers_static_type_offset)) \
|
||||
FIELD(Isolate, class_table_offset) \
|
||||
FIELD(Isolate, current_tag_offset) \
|
||||
FIELD(Isolate, default_tag_offset) \
|
||||
FIELD(Isolate, ic_miss_code_offset) \
|
||||
FIELD(Isolate, object_store_offset) \
|
||||
NOT_IN_PRODUCT(FIELD(Isolate, single_step_offset)) \
|
||||
FIELD(Isolate, user_tag_offset) \
|
||||
FIELD(LinkedHashMap, data_offset) \
|
||||
FIELD(LinkedHashMap, deleted_keys_offset) \
|
||||
FIELD(LinkedHashMap, hash_mask_offset) \
|
||||
FIELD(LinkedHashMap, index_offset) \
|
||||
FIELD(LinkedHashMap, used_data_offset) \
|
||||
FIELD(MarkingStackBlock, pointers_offset) \
|
||||
FIELD(MarkingStackBlock, top_offset) \
|
||||
FIELD(MegamorphicCache, arguments_descriptor_offset) \
|
||||
FIELD(MegamorphicCache, buckets_offset) \
|
||||
FIELD(MegamorphicCache, mask_offset) \
|
||||
FIELD(Mint, value_offset) \
|
||||
FIELD(NativeArguments, argc_tag_offset) \
|
||||
FIELD(NativeArguments, argv_offset) \
|
||||
FIELD(NativeArguments, retval_offset) \
|
||||
FIELD(NativeArguments, thread_offset) \
|
||||
FIELD(ObjectStore, double_type_offset) \
|
||||
FIELD(ObjectStore, int_type_offset) \
|
||||
FIELD(ObjectStore, string_type_offset) \
|
||||
FIELD(OneByteString, data_offset) \
|
||||
FIELD(Pointer, c_memory_address_offset) \
|
||||
FIELD(SingleTargetCache, entry_point_offset) \
|
||||
FIELD(SingleTargetCache, lower_limit_offset) \
|
||||
FIELD(SingleTargetCache, target_offset) \
|
||||
FIELD(SingleTargetCache, upper_limit_offset) \
|
||||
FIELD(StoreBufferBlock, pointers_offset) \
|
||||
FIELD(StoreBufferBlock, top_offset) \
|
||||
FIELD(String, hash_offset) \
|
||||
FIELD(String, length_offset) \
|
||||
FIELD(SubtypeTestCache, cache_offset) \
|
||||
FIELD(Thread, AllocateArray_entry_point_offset) \
|
||||
FIELD(Thread, active_exception_offset) \
|
||||
FIELD(Thread, active_stacktrace_offset) \
|
||||
NOT_IN_DBC(FIELD(Thread, array_write_barrier_code_offset)) \
|
||||
NOT_IN_DBC(FIELD(Thread, array_write_barrier_entry_point_offset)) \
|
||||
FIELD(Thread, async_stack_trace_offset) \
|
||||
FIELD(Thread, auto_scope_native_wrapper_entry_point_offset) \
|
||||
FIELD(Thread, bool_false_offset) \
|
||||
FIELD(Thread, bool_true_offset) \
|
||||
NOT_IN_DBC(FIELD(Thread, call_to_runtime_entry_point_offset)) \
|
||||
NOT_IN_DBC(FIELD(Thread, call_to_runtime_stub_offset)) \
|
||||
FIELD(Thread, dart_stream_offset) \
|
||||
NOT_IN_DBC(FIELD(Thread, deoptimize_entry_offset)) \
|
||||
NOT_IN_DBC(FIELD(Thread, deoptimize_stub_offset)) \
|
||||
FIELD(Thread, double_abs_address_offset) \
|
||||
FIELD(Thread, double_negate_address_offset) \
|
||||
FIELD(Thread, end_offset) \
|
||||
NOT_IN_DBC(FIELD(Thread, enter_safepoint_stub_offset)) \
|
||||
FIELD(Thread, execution_state_offset) \
|
||||
NOT_IN_DBC(FIELD(Thread, exit_safepoint_stub_offset)) \
|
||||
NOT_IN_DBC(FIELD(Thread, fix_allocation_stub_code_offset)) \
|
||||
NOT_IN_DBC(FIELD(Thread, fix_callers_target_code_offset)) \
|
||||
FIELD(Thread, float_absolute_address_offset) \
|
||||
FIELD(Thread, float_negate_address_offset) \
|
||||
FIELD(Thread, float_not_address_offset) \
|
||||
FIELD(Thread, float_zerow_address_offset) \
|
||||
FIELD(Thread, global_object_pool_offset) \
|
||||
NOT_IN_DBC(FIELD(Thread, ic_lookup_through_code_stub_offset)) \
|
||||
NOT_IN_DBC(FIELD(Thread, interpret_call_entry_point_offset)) \
|
||||
NOT_IN_DBC(FIELD(Thread, invoke_dart_code_from_bytecode_stub_offset)) \
|
||||
NOT_IN_DBC(FIELD(Thread, invoke_dart_code_stub_offset)) \
|
||||
FIELD(Thread, isolate_offset) \
|
||||
NOT_IN_DBC(FIELD(Thread, lazy_deopt_from_return_stub_offset)) \
|
||||
NOT_IN_DBC(FIELD(Thread, lazy_deopt_from_throw_stub_offset)) \
|
||||
NOT_IN_DBC(FIELD(Thread, lazy_specialize_type_test_stub_offset)) \
|
||||
FIELD(Thread, marking_stack_block_offset) \
|
||||
NOT_IN_DBC(FIELD(Thread, megamorphic_call_checked_entry_offset)) \
|
||||
NOT_IN_DBC(FIELD(Thread, monomorphic_miss_entry_offset)) \
|
||||
NOT_IN_DBC(FIELD(Thread, monomorphic_miss_stub_offset)) \
|
||||
FIELD(Thread, no_scope_native_wrapper_entry_point_offset) \
|
||||
NOT_IN_DBC( \
|
||||
FIELD(Thread, null_error_shared_with_fpu_regs_entry_point_offset)) \
|
||||
NOT_IN_DBC(FIELD(Thread, null_error_shared_with_fpu_regs_stub_offset)) \
|
||||
NOT_IN_DBC( \
|
||||
FIELD(Thread, null_error_shared_without_fpu_regs_entry_point_offset)) \
|
||||
NOT_IN_DBC(FIELD(Thread, null_error_shared_without_fpu_regs_stub_offset)) \
|
||||
FIELD(Thread, object_null_offset) \
|
||||
FIELD(Thread, predefined_symbols_address_offset) \
|
||||
FIELD(Thread, resume_pc_offset) \
|
||||
FIELD(Thread, safepoint_state_offset) \
|
||||
NOT_IN_DBC(FIELD(Thread, slow_type_test_stub_offset)) \
|
||||
FIELD(Thread, stack_limit_offset) \
|
||||
FIELD(Thread, stack_overflow_flags_offset) \
|
||||
NOT_IN_DBC( \
|
||||
FIELD(Thread, stack_overflow_shared_with_fpu_regs_entry_point_offset)) \
|
||||
NOT_IN_DBC(FIELD(Thread, stack_overflow_shared_with_fpu_regs_stub_offset)) \
|
||||
NOT_IN_DBC(FIELD(Thread, \
|
||||
stack_overflow_shared_without_fpu_regs_entry_point_offset)) \
|
||||
NOT_IN_DBC( \
|
||||
FIELD(Thread, stack_overflow_shared_without_fpu_regs_stub_offset)) \
|
||||
FIELD(Thread, store_buffer_block_offset) \
|
||||
FIELD(Thread, top_exit_frame_info_offset) \
|
||||
FIELD(Thread, top_offset) \
|
||||
FIELD(Thread, top_resource_offset) \
|
||||
FIELD(Thread, unboxed_int64_runtime_arg_offset) \
|
||||
FIELD(Thread, vm_tag_offset) \
|
||||
NOT_IN_DBC(FIELD(Thread, write_barrier_code_offset)) \
|
||||
NOT_IN_DBC(FIELD(Thread, write_barrier_entry_point_offset)) \
|
||||
FIELD(Thread, write_barrier_mask_offset) \
|
||||
NOT_IN_DBC(FIELD(Thread, verify_callback_entry_offset)) \
|
||||
FIELD(Thread, callback_code_offset) \
|
||||
FIELD(TimelineStream, enabled_offset) \
|
||||
FIELD(TwoByteString, data_offset) \
|
||||
FIELD(Type, arguments_offset) \
|
||||
FIELD(Type, hash_offset) \
|
||||
FIELD(Type, signature_offset) \
|
||||
FIELD(Type, type_class_id_offset) \
|
||||
FIELD(Type, type_state_offset) \
|
||||
FIELD(TypeArguments, instantiations_offset) \
|
||||
FIELD(TypeRef, type_offset) \
|
||||
FIELD(TypedDataBase, data_field_offset) \
|
||||
FIELD(TypedDataBase, length_offset) \
|
||||
FIELD(TypedDataView, data_offset) \
|
||||
FIELD(TypedDataView, offset_in_bytes_offset) \
|
||||
FIELD(TypedData, data_offset) \
|
||||
FIELD(UserTag, tag_offset) \
|
||||
ARRAY(Array, element_offset) \
|
||||
ARRAY(TypeArguments, type_at_offset) \
|
||||
NOT_IN_PRODUCT(ARRAY(ClassTable, ClassOffsetFor)) \
|
||||
NOT_IN_PRODUCT(ARRAY_STRUCTFIELD( \
|
||||
ClassTable, NewSpaceCounterOffsetFor, ClassOffsetFor, \
|
||||
ClassHeapStats::allocated_since_gc_new_space_offset())) \
|
||||
NOT_IN_PRODUCT(ARRAY_STRUCTFIELD( \
|
||||
ClassTable, StateOffsetFor, ClassOffsetFor, \
|
||||
ClassHeapStats::allocated_since_gc_new_space_offset())) \
|
||||
NOT_IN_PRODUCT(ARRAY_STRUCTFIELD( \
|
||||
ClassTable, NewSpaceSizeOffsetFor, ClassOffsetFor, \
|
||||
ClassHeapStats::allocated_size_since_gc_new_space_offset())) \
|
||||
NOT_IN_PRODUCT(FIELD(ClassTable, class_heap_stats_table_offset)) \
|
||||
RANGE(Code, entry_point_offset, CodeEntryKind, CodeEntryKind::kNormal, \
|
||||
CodeEntryKind::kMonomorphicUnchecked, \
|
||||
[](CodeEntryKind value) { return true; }) \
|
||||
RANGE(Code, function_entry_point_offset, CodeEntryKind, \
|
||||
CodeEntryKind::kNormal, CodeEntryKind::kUnchecked, \
|
||||
[](CodeEntryKind value) { return true; }) \
|
||||
ONLY_IN_ARM_ARM64_X64(RANGE( \
|
||||
Thread, write_barrier_wrappers_thread_offset, Register, 0, \
|
||||
kNumberOfCpuRegisters - 1, \
|
||||
[](Register reg) { return (kDartAvailableCpuRegs & (1 << reg)) != 0; })) \
|
||||
SIZEOF(Array, header_size, RawArray) \
|
||||
SIZEOF(Context, header_size, RawContext) \
|
||||
SIZEOF(Double, InstanceSize, RawDouble) \
|
||||
SIZEOF(Float32x4, InstanceSize, RawFloat32x4) \
|
||||
SIZEOF(Float64x2, InstanceSize, RawFloat64x2) \
|
||||
SIZEOF(Instructions, UnalignedHeaderSize, RawInstructions) \
|
||||
SIZEOF(Int32x4, InstanceSize, RawInt32x4) \
|
||||
SIZEOF(Mint, InstanceSize, RawMint) \
|
||||
SIZEOF(NativeArguments, StructSize, NativeArguments) \
|
||||
SIZEOF(String, InstanceSize, RawString) \
|
||||
SIZEOF(TypedData, InstanceSize, RawTypedData)
|
||||
|
||||
#endif // RUNTIME_VM_COMPILER_RUNTIME_OFFSETS_LIST_H_
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "vm/clustered_snapshot.h"
|
||||
#include "vm/code_observers.h"
|
||||
#include "vm/compiler/runtime_offsets_extracted.h"
|
||||
#include "vm/compiler/runtime_offsets_list.h"
|
||||
#include "vm/cpu.h"
|
||||
#include "vm/dart_api_state.h"
|
||||
#include "vm/dart_entry.h"
|
||||
|
@ -22,6 +24,7 @@
|
|||
#include "vm/malloc_hooks.h"
|
||||
#include "vm/message_handler.h"
|
||||
#include "vm/metrics.h"
|
||||
#include "vm/native_entry.h"
|
||||
#include "vm/object.h"
|
||||
#include "vm/object_id_ring.h"
|
||||
#include "vm/object_store.h"
|
||||
|
@ -84,36 +87,40 @@ class ReadOnlyHandles {
|
|||
};
|
||||
|
||||
static void CheckOffsets() {
|
||||
// These offsets are embedded in precompiled instructions. We need the
|
||||
// compiler and the runtime to agree.
|
||||
bool ok = true;
|
||||
#define CHECK_OFFSET(expr, offset) \
|
||||
if ((expr) != (offset)) { \
|
||||
OS::PrintErr("%s got %" Pd " expected %" Pd "\n", #expr, (expr), \
|
||||
OS::PrintErr("%s got %" Pd ", %s expected %" Pd "\n", #expr, \
|
||||
static_cast<intptr_t>(expr), #offset, \
|
||||
static_cast<intptr_t>(offset)); \
|
||||
ok = false; \
|
||||
}
|
||||
|
||||
#if defined(TARGET_ARCH_ARM)
|
||||
// These offsets are embedded in precompiled instructions. We need simarm
|
||||
// (compiler) and arm (runtime) to agree.
|
||||
CHECK_OFFSET(Thread::stack_limit_offset(), 36);
|
||||
CHECK_OFFSET(Thread::object_null_offset(), 96);
|
||||
CHECK_OFFSET(SingleTargetCache::upper_limit_offset(), 14);
|
||||
CHECK_OFFSET(Isolate::object_store_offset(), 20);
|
||||
NOT_IN_PRODUCT(CHECK_OFFSET(sizeof(ClassHeapStats), 168));
|
||||
#endif
|
||||
#if defined(TARGET_ARCH_ARM64)
|
||||
// These offsets are embedded in precompiled instructions. We need simarm64
|
||||
// (compiler) and arm64 (runtime) to agree.
|
||||
CHECK_OFFSET(Thread::stack_limit_offset(), 72);
|
||||
CHECK_OFFSET(Thread::object_null_offset(), 184);
|
||||
CHECK_OFFSET(SingleTargetCache::upper_limit_offset(), 26);
|
||||
CHECK_OFFSET(Isolate::object_store_offset(), 40);
|
||||
NOT_IN_PRODUCT(CHECK_OFFSET(sizeof(ClassHeapStats), 288));
|
||||
#endif
|
||||
#define CHECK_FIELD(Class, Name) CHECK_OFFSET(Class::Name(), Class##_##Name)
|
||||
#define CHECK_ARRAY(Class, Name) \
|
||||
CHECK_OFFSET(Class::ArrayLayout::elements_start_offset(), \
|
||||
Class##_elements_start_offset) \
|
||||
CHECK_OFFSET(Class::ArrayLayout::kElementSize, Class##_element_size)
|
||||
#define CHECK_ARRAY_STRUCTFIELD(Class, Name, ElementOffsetName, FieldOffset)
|
||||
#define CHECK_SIZEOF(Class, Name, What) \
|
||||
CHECK_OFFSET(sizeof(What), Class##_##Name)
|
||||
#define CHECK_RANGE(Class, Name, Type, First, Last, Filter)
|
||||
#define CHECK_CONSTANT(Class, Name) CHECK_OFFSET(Class::Name, Class##_##Name)
|
||||
|
||||
OFFSETS_LIST(CHECK_FIELD, CHECK_ARRAY, CHECK_ARRAY_STRUCTFIELD, CHECK_SIZEOF,
|
||||
CHECK_RANGE, CHECK_CONSTANT, NOT_IN_PRECOMPILED_RUNTIME)
|
||||
|
||||
if (!ok) {
|
||||
FATAL("CheckOffsets failed.");
|
||||
}
|
||||
#undef CHECK_FIELD
|
||||
#undef CHECK_ARRAY
|
||||
#undef CHECK_ARRAY_STRUCTFIELD
|
||||
#undef CHECK_SIZEOF
|
||||
#undef CHECK_RANGE
|
||||
#undef CHECK_CONSTANT
|
||||
#undef CHECK_OFFSET
|
||||
}
|
||||
|
||||
|
|
|
@ -377,22 +377,6 @@ RawArray* ArgumentsDescriptor::GetArgumentNames() const {
|
|||
return names.raw();
|
||||
}
|
||||
|
||||
intptr_t ArgumentsDescriptor::type_args_len_offset() {
|
||||
return Array::element_offset(kTypeArgsLenIndex);
|
||||
}
|
||||
|
||||
intptr_t ArgumentsDescriptor::count_offset() {
|
||||
return Array::element_offset(kCountIndex);
|
||||
}
|
||||
|
||||
intptr_t ArgumentsDescriptor::positional_count_offset() {
|
||||
return Array::element_offset(kPositionalCountIndex);
|
||||
}
|
||||
|
||||
intptr_t ArgumentsDescriptor::first_named_entry_offset() {
|
||||
return Array::element_offset(kFirstNamedEntryIndex);
|
||||
}
|
||||
|
||||
RawArray* ArgumentsDescriptor::New(intptr_t type_args_len,
|
||||
intptr_t num_arguments,
|
||||
const Array& optional_arguments_names) {
|
||||
|
|
|
@ -49,10 +49,20 @@ class ArgumentsDescriptor : public ValueObject {
|
|||
RawArray* GetArgumentNames() const;
|
||||
|
||||
// Generated code support.
|
||||
static intptr_t type_args_len_offset();
|
||||
static intptr_t count_offset();
|
||||
static intptr_t positional_count_offset();
|
||||
static intptr_t first_named_entry_offset();
|
||||
static intptr_t type_args_len_offset() {
|
||||
return Array::element_offset(kTypeArgsLenIndex);
|
||||
}
|
||||
|
||||
static intptr_t count_offset() { return Array::element_offset(kCountIndex); }
|
||||
|
||||
static intptr_t positional_count_offset() {
|
||||
return Array::element_offset(kPositionalCountIndex);
|
||||
}
|
||||
|
||||
static intptr_t first_named_entry_offset() {
|
||||
return Array::element_offset(kFirstNamedEntryIndex);
|
||||
}
|
||||
|
||||
static intptr_t name_offset() { return kNameOffset * kWordSize; }
|
||||
static intptr_t position_offset() { return kPositionOffset * kWordSize; }
|
||||
static intptr_t named_entry_size() { return kNamedEntrySize * kWordSize; }
|
||||
|
|
|
@ -73,6 +73,25 @@ const intptr_t kDefaultMaxOldGenHeapSize = (kWordSize <= 4) ? 1536 : 0;
|
|||
#define NOT_IN_PRECOMPILED(code) code
|
||||
#endif // defined(DART_PRECOMPILED_RUNTIME)
|
||||
|
||||
#if defined(TARGET_ARCH_DBC)
|
||||
#define NOT_IN_DBC(code)
|
||||
#else
|
||||
#define NOT_IN_DBC(code) code
|
||||
#endif // defined(TARGET_ARCH_DBC)
|
||||
|
||||
#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64) || \
|
||||
defined(TARGET_ARCH_X64)
|
||||
#define ONLY_IN_ARM_ARM64_X64(code) code
|
||||
#else
|
||||
#define ONLY_IN_ARM_ARM64_X64(code)
|
||||
#endif
|
||||
|
||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||
#define NOT_IN_PRECOMPILED_RUNTIME(code)
|
||||
#else
|
||||
#define NOT_IN_PRECOMPILED_RUNTIME(code) code
|
||||
#endif // defined(DART_PRECOMPILED_RUNTIME)
|
||||
|
||||
#if !defined(PRODUCT) || defined(HOST_OS_FUCHSIA) || defined(TARGET_OS_FUCHSIA)
|
||||
#define SUPPORT_TIMELINE 1
|
||||
#endif
|
||||
|
|
|
@ -4318,6 +4318,14 @@ class ObjectPool : public Object {
|
|||
sizeof(RawObjectPool::Entry) * index;
|
||||
}
|
||||
|
||||
struct ArrayLayout {
|
||||
static intptr_t elements_start_offset() {
|
||||
return ObjectPool::data_offset();
|
||||
}
|
||||
|
||||
static constexpr intptr_t kElementSize = sizeof(RawObjectPool::Entry);
|
||||
};
|
||||
|
||||
EntryType TypeAt(intptr_t index) const {
|
||||
return TypeBits::decode(raw_ptr()->entry_bits()[index]);
|
||||
}
|
||||
|
@ -6265,6 +6273,14 @@ class TypeArguments : public Instance {
|
|||
}
|
||||
void SetTypeAt(intptr_t index, const AbstractType& value) const;
|
||||
|
||||
struct ArrayLayout {
|
||||
static intptr_t elements_start_offset() {
|
||||
return TypeArguments::type_at_offset(0);
|
||||
}
|
||||
|
||||
static constexpr intptr_t kElementSize = kWordSize;
|
||||
};
|
||||
|
||||
// The name of this type argument vector, e.g. "<T, dynamic, List<T>, Smi>".
|
||||
RawString* Name() const { return SubvectorName(0, Length(), kInternalName); }
|
||||
|
||||
|
@ -8046,6 +8062,12 @@ class Array : public Instance {
|
|||
return OFFSET_OF_RETURNED_VALUE(RawArray, data) + kWordSize * index;
|
||||
}
|
||||
|
||||
struct ArrayLayout {
|
||||
static intptr_t elements_start_offset() { return Array::data_offset(); }
|
||||
|
||||
static constexpr intptr_t kElementSize = kWordSize;
|
||||
};
|
||||
|
||||
static bool Equals(RawArray* a, RawArray* b) {
|
||||
if (a == b) return true;
|
||||
if (a->IsRawNull() || b->IsRawNull()) return false;
|
||||
|
|
|
@ -1404,15 +1404,14 @@ class RawInstructions : public RawObject {
|
|||
uint32_t size_and_flags_;
|
||||
uint32_t unchecked_entrypoint_pc_offset_;
|
||||
|
||||
#if defined(DART_PRECOMPILER)
|
||||
// There is a gap between size_and_flags_ and the entry point
|
||||
// because we align entry point by 4 words on all platforms.
|
||||
// This allows us to have a free field here without affecting
|
||||
// the aligned size of the Instructions object header.
|
||||
// This also means that entry point offset is the same
|
||||
// whether this field is included or excluded.
|
||||
// TODO(37103): This field should be removed.
|
||||
CodeStatistics* stats_;
|
||||
#endif
|
||||
|
||||
// Variable length data follows here.
|
||||
uint8_t* data() { OPEN_ARRAY_START(uint8_t, uint8_t); }
|
||||
|
|
42
tools/run_offsets_extractor.sh
Executable file
42
tools/run_offsets_extractor.sh
Executable file
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/env bash
|
||||
# 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.
|
||||
|
||||
set -e
|
||||
|
||||
FILE="runtime/vm/compiler/runtime_offsets_extracted.h"
|
||||
|
||||
# Make sure we're running in the SDK directory.
|
||||
if ! test -f "$FILE"; then
|
||||
echo "Couldn't find $FILE"
|
||||
echo "Make sure to run this script from the Dart SDK directory."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# We're regenerating the file, but we want to keep all the comments etc at the
|
||||
# top of the file. So just delete everything after the first "#if defined".
|
||||
LINE=$(grep "#if defined" "$FILE" -n | head -n 1 | sed "s/^\([0-9]*\):.*/\1/")
|
||||
TEMP="${FILE}.temp"
|
||||
head -n $(expr $LINE - 1) "$FILE" >"$TEMP"
|
||||
|
||||
# Run offsets_extractor for every architecture and append the results.
|
||||
run() {
|
||||
echo "" >>"$TEMP"
|
||||
tools/gn.py --mode=release --arch=$1
|
||||
tools/build.py --mode=release --arch=$1 offsets_extractor
|
||||
out/$2/offsets_extractor >>"$TEMP"
|
||||
}
|
||||
run simarm ReleaseSIMARM
|
||||
run x64 ReleaseX64
|
||||
run ia32 ReleaseIA32
|
||||
run simarm64 ReleaseSIMARM64
|
||||
run simdbc64 ReleaseSIMDBC64
|
||||
run simdbc ReleaseSIMDBC
|
||||
|
||||
# Cleanup.
|
||||
echo "" >>"$TEMP"
|
||||
echo "#endif // RUNTIME_VM_COMPILER_RUNTIME_OFFSETS_EXTRACTED_H_" >>"$TEMP"
|
||||
mv "$TEMP" "$FILE"
|
||||
git cl format "$FILE"
|
||||
echo -e "\n\nSuccessfully generated $FILE :)"
|
Loading…
Reference in a new issue