Reland "[vm, compiler] Reduce alignment of Instructions and remove some debugging trap instructions."
Fix generating assembly from simarm_x64. Bug: https://github.com/dart-lang/sdk/issues/37103 Bug: https://github.com/dart-lang/sdk/issues/38452 Change-Id: Ic3402beb0278dc483ba82874cb573ce26b8669b2 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/118702 Commit-Queue: Ryan Macnak <rmacnak@google.com> Reviewed-by: Aart Bik <ajcbik@google.com> Reviewed-by: Liam Appelbe <liama@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
87d795c177
commit
44da8af04f
@@ -167,9 +167,10 @@ void CodeStatistics::Finalize() {
|
||||
intptr_t function_size = assembler_->CodeSize();
|
||||
unaccounted_bytes_ = function_size - instruction_bytes_;
|
||||
ASSERT(unaccounted_bytes_ >= 0);
|
||||
|
||||
const intptr_t unaligned_bytes = Instructions::HeaderSize() + function_size;
|
||||
alignment_bytes_ =
|
||||
Utils::RoundUp(function_size, OS::PreferredCodeAlignment()) -
|
||||
function_size;
|
||||
Utils::RoundUp(unaligned_bytes, kObjectAlignment) - unaligned_bytes;
|
||||
assembler_ = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -952,7 +952,9 @@ void FlowGraphCompiler::CompileGraph() {
|
||||
|
||||
VisitBlocks();
|
||||
|
||||
#if defined(DEBUG)
|
||||
__ bkpt(0);
|
||||
#endif
|
||||
|
||||
if (!skip_body_compilation()) {
|
||||
ASSERT(assembler()->constant_pool_allowed());
|
||||
|
||||
@@ -920,7 +920,9 @@ void FlowGraphCompiler::CompileGraph() {
|
||||
|
||||
VisitBlocks();
|
||||
|
||||
#if defined(DEBUG)
|
||||
__ brk(0);
|
||||
#endif
|
||||
|
||||
if (!skip_body_compilation()) {
|
||||
ASSERT(assembler()->constant_pool_allowed());
|
||||
|
||||
@@ -839,7 +839,9 @@ void FlowGraphCompiler::CompileGraph() {
|
||||
VisitBlocks();
|
||||
|
||||
if (!skip_body_compilation()) {
|
||||
#if defined(DEBUG)
|
||||
__ int3();
|
||||
#endif
|
||||
GenerateDeferredCode();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -935,7 +935,9 @@ void FlowGraphCompiler::CompileGraph() {
|
||||
ASSERT(!block_order().is_empty());
|
||||
VisitBlocks();
|
||||
|
||||
#if defined(DEBUG)
|
||||
__ int3();
|
||||
#endif
|
||||
|
||||
if (!skip_body_compilation()) {
|
||||
ASSERT(assembler()->constant_pool_allowed());
|
||||
|
||||
@@ -510,7 +510,9 @@ static void EmitAssertBoolean(Register reg,
|
||||
compiler->GenerateRuntimeCall(token_pos, deopt_id,
|
||||
kNonBoolTypeErrorRuntimeEntry, 1, locs);
|
||||
// We should never return here.
|
||||
#if defined(DEBUG)
|
||||
__ bkpt(0);
|
||||
#endif
|
||||
__ Bind(&done);
|
||||
}
|
||||
|
||||
|
||||
@@ -499,7 +499,9 @@ static void EmitAssertBoolean(Register reg,
|
||||
compiler->GenerateRuntimeCall(token_pos, deopt_id,
|
||||
kNonBoolTypeErrorRuntimeEntry, 1, locs);
|
||||
// We should never return here.
|
||||
#if defined(DEBUG)
|
||||
__ brk(0);
|
||||
#endif
|
||||
__ Bind(&done);
|
||||
}
|
||||
|
||||
|
||||
@@ -392,7 +392,9 @@ static void EmitAssertBoolean(Register reg,
|
||||
compiler->GenerateRuntimeCall(token_pos, deopt_id,
|
||||
kNonBoolTypeErrorRuntimeEntry, 1, locs);
|
||||
// We should never return here.
|
||||
#if defined(DEBUG)
|
||||
__ int3();
|
||||
#endif
|
||||
__ Bind(&done);
|
||||
}
|
||||
|
||||
|
||||
@@ -521,7 +521,9 @@ static void EmitAssertBoolean(Register reg,
|
||||
compiler->GenerateRuntimeCall(token_pos, deopt_id,
|
||||
kNonBoolTypeErrorRuntimeEntry, 1, locs);
|
||||
// We should never return here.
|
||||
#if defined(DEBUG)
|
||||
__ int3();
|
||||
#endif
|
||||
__ Bind(&done);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,9 +21,12 @@ DEFINE_FLAG(bool,
|
||||
false,
|
||||
"Generate always trampolines (for testing purposes).");
|
||||
|
||||
// The trampolines will have a 1-word object header in front of them.
|
||||
// The trampolines will be disguised as FreeListElement objects, with a 1-word
|
||||
// object header in front of the jump code.
|
||||
const intptr_t kOffsetInTrampoline = kWordSize;
|
||||
const intptr_t kTrampolineSize = OS::kMaxPreferredCodeAlignment;
|
||||
const intptr_t kTrampolineSize = Utils::RoundUp(
|
||||
kOffsetInTrampoline + PcRelativeTrampolineJumpPattern::kLengthInBytes,
|
||||
kObjectAlignment);
|
||||
|
||||
CodeRelocator::CodeRelocator(Thread* thread,
|
||||
GrowableArray<RawCode*>* code_objects,
|
||||
@@ -408,7 +411,12 @@ bool CodeRelocator::IsTargetInRangeFor(UnresolvedCall* unresolved_call,
|
||||
static void MarkAsFreeListElement(uint8_t* trampoline_bytes,
|
||||
intptr_t trampoline_length) {
|
||||
uint32_t tags = 0;
|
||||
#if defined(IS_SIMARM_X64)
|
||||
// Account for difference in kObjectAlignment between host and target.
|
||||
tags = RawObject::SizeTag::update(trampoline_length * 2, tags);
|
||||
#else
|
||||
tags = RawObject::SizeTag::update(trampoline_length, tags);
|
||||
#endif
|
||||
tags = RawObject::ClassIdTag::update(kFreeListElement, tags);
|
||||
tags = RawObject::OldBit::update(true, tags);
|
||||
tags = RawObject::OldAndNotMarkedBit::update(true, tags);
|
||||
@@ -464,9 +472,6 @@ void CodeRelocator::BuildTrampolinesForAlmostOutOfRangeCalls() {
|
||||
// buffer.
|
||||
auto trampoline_bytes = new uint8_t[kTrampolineSize];
|
||||
memset(trampoline_bytes, 0x00, kTrampolineSize);
|
||||
ASSERT((kOffsetInTrampoline +
|
||||
PcRelativeTrampolineJumpPattern::kLengthInBytes) <
|
||||
kTrampolineSize);
|
||||
auto unresolved_trampoline = new UnresolvedTrampoline{
|
||||
unresolved_call->callee,
|
||||
unresolved_call->offset_into_target,
|
||||
|
||||
@@ -505,11 +505,7 @@ const word StoreBufferBlock::kSize = dart::StoreBufferBlock::kSize;
|
||||
const word MarkingStackBlock::kSize = dart::MarkingStackBlock::kSize;
|
||||
|
||||
word Instructions::HeaderSize() {
|
||||
intptr_t alignment = OS::PreferredCodeAlignment();
|
||||
intptr_t aligned_size =
|
||||
Utils::RoundUp(Instructions::UnalignedHeaderSize(), alignment);
|
||||
ASSERT(aligned_size == alignment);
|
||||
return aligned_size;
|
||||
return Utils::RoundUp(Instructions::UnalignedHeaderSize(), target::kWordSize);
|
||||
}
|
||||
|
||||
#if !defined(TARGET_ARCH_DBC)
|
||||
|
||||
@@ -355,7 +355,7 @@ static constexpr dart::compiler::target::word Double_InstanceSize = 16;
|
||||
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
|
||||
16;
|
||||
12;
|
||||
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word Mint_InstanceSize = 16;
|
||||
static constexpr dart::compiler::target::word NativeArguments_StructSize = 16;
|
||||
@@ -714,7 +714,7 @@ static constexpr dart::compiler::target::word Double_InstanceSize = 16;
|
||||
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
|
||||
24;
|
||||
16;
|
||||
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word Mint_InstanceSize = 16;
|
||||
static constexpr dart::compiler::target::word NativeArguments_StructSize = 32;
|
||||
@@ -1065,7 +1065,7 @@ static constexpr dart::compiler::target::word Double_InstanceSize = 16;
|
||||
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
|
||||
16;
|
||||
12;
|
||||
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word Mint_InstanceSize = 16;
|
||||
static constexpr dart::compiler::target::word NativeArguments_StructSize = 16;
|
||||
@@ -1425,7 +1425,7 @@ static constexpr dart::compiler::target::word Double_InstanceSize = 16;
|
||||
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
|
||||
24;
|
||||
16;
|
||||
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word Mint_InstanceSize = 16;
|
||||
static constexpr dart::compiler::target::word NativeArguments_StructSize = 32;
|
||||
@@ -1712,7 +1712,7 @@ static constexpr dart::compiler::target::word Double_InstanceSize = 16;
|
||||
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
|
||||
24;
|
||||
16;
|
||||
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word Mint_InstanceSize = 16;
|
||||
static constexpr dart::compiler::target::word NativeArguments_StructSize = 32;
|
||||
@@ -1996,7 +1996,7 @@ static constexpr dart::compiler::target::word Double_InstanceSize = 16;
|
||||
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word Instructions_UnalignedHeaderSize =
|
||||
16;
|
||||
12;
|
||||
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
|
||||
static constexpr dart::compiler::target::word Mint_InstanceSize = 16;
|
||||
static constexpr dart::compiler::target::word NativeArguments_StructSize = 16;
|
||||
|
||||
@@ -1319,6 +1319,7 @@ void PageSpace::SetupImagePage(void* pointer, uword size, bool is_executable) {
|
||||
// memory->end()).
|
||||
uword offset = HeapPage::ObjectStartOffset();
|
||||
pointer = reinterpret_cast<void*>(reinterpret_cast<uword>(pointer) - offset);
|
||||
ASSERT(Utils::IsAligned(pointer, kObjectAlignment));
|
||||
size += offset;
|
||||
|
||||
VirtualMemory* memory = VirtualMemory::ForImagePage(pointer, size);
|
||||
@@ -1331,7 +1332,6 @@ void PageSpace::SetupImagePage(void* pointer, uword size, bool is_executable) {
|
||||
page->forwarding_page_ = NULL;
|
||||
page->card_table_ = NULL;
|
||||
if (is_executable) {
|
||||
ASSERT(Utils::IsAligned(pointer, OS::PreferredCodeAlignment()));
|
||||
page->type_ = HeapPage::kExecutable;
|
||||
} else {
|
||||
page->type_ = HeapPage::kData;
|
||||
|
||||
@@ -65,7 +65,7 @@ class HeapPage {
|
||||
void WriteProtect(bool read_only);
|
||||
|
||||
static intptr_t ObjectStartOffset() {
|
||||
return Utils::RoundUp(sizeof(HeapPage), OS::kMaxPreferredCodeAlignment);
|
||||
return Utils::RoundUp(sizeof(HeapPage), kMaxObjectAlignment);
|
||||
}
|
||||
|
||||
// Warning: This does not work for objects on image pages because image pages
|
||||
|
||||
@@ -220,12 +220,9 @@ static intptr_t PcDescriptorsSizeInSnapshot(intptr_t len) {
|
||||
compiler::target::ObjectAlignment::kObjectAlignment);
|
||||
}
|
||||
|
||||
static constexpr intptr_t kSimarmX64InstructionsAlignment =
|
||||
2 * compiler::target::ObjectAlignment::kObjectAlignment;
|
||||
static intptr_t InstructionsSizeInSnapshot(intptr_t len) {
|
||||
const intptr_t header_size = Utils::RoundUp(3 * compiler::target::kWordSize,
|
||||
kSimarmX64InstructionsAlignment);
|
||||
return header_size + Utils::RoundUp(len, kSimarmX64InstructionsAlignment);
|
||||
return Utils::RoundUp(compiler::target::Instructions::HeaderSize() + len,
|
||||
compiler::target::ObjectAlignment::kObjectAlignment);
|
||||
}
|
||||
|
||||
intptr_t ImageWriter::SizeInSnapshot(RawObject* raw_object) {
|
||||
@@ -398,15 +395,15 @@ void ImageWriter::Write(WriteStream* clustered_stream, bool vm) {
|
||||
}
|
||||
|
||||
void ImageWriter::WriteROData(WriteStream* stream) {
|
||||
stream->Align(OS::kMaxPreferredCodeAlignment);
|
||||
stream->Align(kMaxObjectAlignment);
|
||||
|
||||
// Heap page starts here.
|
||||
|
||||
intptr_t section_start = stream->Position();
|
||||
|
||||
stream->WriteWord(next_data_offset_); // Data length.
|
||||
COMPILE_ASSERT(OS::kMaxPreferredCodeAlignment >= kObjectAlignment);
|
||||
stream->Align(OS::kMaxPreferredCodeAlignment);
|
||||
COMPILE_ASSERT(kMaxObjectAlignment >= kObjectAlignment);
|
||||
stream->Align(kMaxObjectAlignment);
|
||||
|
||||
ASSERT(stream->Position() - section_start == Image::kHeaderSize);
|
||||
|
||||
@@ -522,6 +519,7 @@ void AssemblyImageWriter::Finalize() {
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||
static void EnsureAssemblerIdentifier(char* label) {
|
||||
for (char c = *label; c != '\0'; c = *++label) {
|
||||
if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) ||
|
||||
@@ -532,8 +530,8 @@ static void EnsureAssemblerIdentifier(char* label) {
|
||||
}
|
||||
}
|
||||
|
||||
const char* NameOfStubIsolateSpecificStub(ObjectStore* object_store,
|
||||
const Code& code) {
|
||||
static const char* NameOfStubIsolateSpecificStub(ObjectStore* object_store,
|
||||
const Code& code) {
|
||||
if (code.raw() == object_store->build_method_extractor_code()) {
|
||||
return "_iso_stub_BuildMethodExtractorStub";
|
||||
} else if (code.raw() == object_store->null_error_stub_with_fpu_regs_stub()) {
|
||||
@@ -554,8 +552,12 @@ const char* NameOfStubIsolateSpecificStub(ObjectStore* object_store,
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
||||
|
||||
void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||
#if defined(DART_PRECOMPILED_RUNTIME)
|
||||
UNREACHABLE();
|
||||
#else
|
||||
Zone* zone = Thread::Current()->zone();
|
||||
|
||||
#if defined(DART_PRECOMPILER)
|
||||
@@ -569,7 +571,7 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||
assembly_stream_.Print(".globl %s\n", instructions_symbol);
|
||||
|
||||
// Start snapshot at page boundary.
|
||||
ASSERT(VirtualMemory::PageSize() >= OS::kMaxPreferredCodeAlignment);
|
||||
ASSERT(VirtualMemory::PageSize() >= kMaxObjectAlignment);
|
||||
assembly_stream_.Print(".balign %" Pd ", 0\n", VirtualMemory::PageSize());
|
||||
assembly_stream_.Print("%s:\n", instructions_symbol);
|
||||
|
||||
@@ -640,8 +642,6 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||
SizeInSnapshot(insns.raw()));
|
||||
}
|
||||
|
||||
ASSERT(insns.raw()->HeapSize() % sizeof(uint64_t) == 0);
|
||||
|
||||
// 1. Write from the header to the entry point.
|
||||
{
|
||||
NoSafepointScope no_safepoint;
|
||||
@@ -668,8 +668,6 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||
text_offset += sizeof(compiler::target::uword);
|
||||
WriteWordLiteralText(insns.raw_ptr()->unchecked_entrypoint_pc_offset_);
|
||||
text_offset += sizeof(compiler::target::uword);
|
||||
WriteWordLiteralText(0);
|
||||
text_offset += sizeof(compiler::target::uword);
|
||||
#else // defined(IS_SIMARM_X64)
|
||||
uword beginning = reinterpret_cast<uword>(insns.raw_ptr());
|
||||
uword entry = beginning + Instructions::HeaderSize();
|
||||
@@ -726,14 +724,12 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||
{
|
||||
// 3. Write from the entry point to the end.
|
||||
NoSafepointScope no_safepoint;
|
||||
uword beginning = reinterpret_cast<uword>(insns.raw_ptr());
|
||||
uword entry = beginning + Instructions::HeaderSize();
|
||||
uword payload_size = insns.raw()->HeapSize() - insns.HeaderSize();
|
||||
uword end = entry + payload_size;
|
||||
uword entry = insns.PayloadStart();
|
||||
uword end = entry + SizeInSnapshot(insns.raw()) -
|
||||
compiler::target::Instructions::Instructions::HeaderSize();
|
||||
|
||||
ASSERT(Utils::IsAligned(beginning, sizeof(uword)));
|
||||
ASSERT(Utils::IsAligned(entry, sizeof(uword)));
|
||||
ASSERT(Utils::IsAligned(end, sizeof(uword)));
|
||||
ASSERT(Utils::IsAligned(entry, sizeof(compiler::target::uword)));
|
||||
ASSERT(Utils::IsAligned(end, sizeof(compiler::target::uword)));
|
||||
|
||||
#if defined(DART_PRECOMPILER)
|
||||
PcDescriptors::Iterator iterator(descriptors,
|
||||
@@ -759,6 +755,8 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||
ASSERT(kWordSize != compiler::target::kWordSize ||
|
||||
(text_offset - instr_start) == insns.raw()->HeapSize());
|
||||
}
|
||||
|
||||
ASSERT((text_offset - instr_start) == SizeInSnapshot(insns.raw()));
|
||||
}
|
||||
|
||||
FrameUnwindEpilogue();
|
||||
@@ -785,12 +783,12 @@ void AssemblyImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||
const char* data_symbol =
|
||||
vm ? "_kDartVmSnapshotData" : "_kDartIsolateSnapshotData";
|
||||
assembly_stream_.Print(".globl %s\n", data_symbol);
|
||||
assembly_stream_.Print(".balign %" Pd ", 0\n",
|
||||
OS::kMaxPreferredCodeAlignment);
|
||||
assembly_stream_.Print(".balign %" Pd ", 0\n", kMaxObjectAlignment);
|
||||
assembly_stream_.Print("%s:\n", data_symbol);
|
||||
uword buffer = reinterpret_cast<uword>(clustered_stream->buffer());
|
||||
intptr_t length = clustered_stream->bytes_written();
|
||||
WriteByteSequence(buffer, buffer + length);
|
||||
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
||||
}
|
||||
|
||||
void AssemblyImageWriter::FrameUnwindPrologue() {
|
||||
@@ -966,8 +964,10 @@ void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||
|
||||
uword beginning = reinterpret_cast<uword>(insns.raw_ptr());
|
||||
uword entry = beginning + Instructions::HeaderSize();
|
||||
uword payload_size = insns.Size();
|
||||
payload_size = Utils::RoundUp(payload_size, OS::PreferredCodeAlignment());
|
||||
uword payload_size =
|
||||
Utils::RoundUp(Instructions::HeaderSize() + insns.Size(),
|
||||
compiler::target::ObjectAlignment::kObjectAlignment) -
|
||||
Instructions::HeaderSize();
|
||||
uword end = entry + payload_size;
|
||||
|
||||
ASSERT(Utils::IsAligned(beginning, sizeof(uword)));
|
||||
@@ -1005,11 +1005,11 @@ void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
|
||||
insns.raw_ptr()->size_and_flags_);
|
||||
instructions_blob_stream_.WriteFixed<uint32_t>(
|
||||
insns.raw_ptr()->unchecked_entrypoint_pc_offset_);
|
||||
instructions_blob_stream_.Align(kSimarmX64InstructionsAlignment);
|
||||
payload_stream_start = instructions_blob_stream_.Position();
|
||||
instructions_blob_stream_.WriteBytes(
|
||||
reinterpret_cast<const void*>(insns.PayloadStart()), insns.Size());
|
||||
instructions_blob_stream_.Align(kSimarmX64InstructionsAlignment);
|
||||
instructions_blob_stream_.Align(
|
||||
compiler::target::ObjectAlignment::kObjectAlignment);
|
||||
const intptr_t end_offset = instructions_blob_stream_.bytes_written();
|
||||
text_offset += (end_offset - start_offset);
|
||||
USE(end);
|
||||
@@ -1101,9 +1101,8 @@ ImageReader::ImageReader(const uint8_t* data_image,
|
||||
RawApiError* ImageReader::VerifyAlignment() const {
|
||||
if (!Utils::IsAligned(data_image_, kObjectAlignment) ||
|
||||
!Utils::IsAligned(shared_data_image_, kObjectAlignment) ||
|
||||
!Utils::IsAligned(instructions_image_, OS::PreferredCodeAlignment()) ||
|
||||
!Utils::IsAligned(shared_instructions_image_,
|
||||
OS::PreferredCodeAlignment())) {
|
||||
!Utils::IsAligned(instructions_image_, kMaxObjectAlignment) ||
|
||||
!Utils::IsAligned(shared_instructions_image_, kMaxObjectAlignment)) {
|
||||
return ApiError::New(
|
||||
String::Handle(String::New("Snapshot is misaligned", Heap::kOld)),
|
||||
Heap::kOld);
|
||||
@@ -1112,7 +1111,7 @@ RawApiError* ImageReader::VerifyAlignment() const {
|
||||
}
|
||||
|
||||
RawInstructions* ImageReader::GetInstructionsAt(int32_t offset) const {
|
||||
ASSERT(Utils::IsAligned(offset, OS::PreferredCodeAlignment()));
|
||||
ASSERT(Utils::IsAligned(offset, kObjectAlignment));
|
||||
|
||||
RawObject* result;
|
||||
if (offset < 0) {
|
||||
|
||||
@@ -35,7 +35,7 @@ class RawObject;
|
||||
class Image : ValueObject {
|
||||
public:
|
||||
explicit Image(const void* raw_memory) : raw_memory_(raw_memory) {
|
||||
ASSERT(Utils::IsAligned(raw_memory, OS::kMaxPreferredCodeAlignment));
|
||||
ASSERT(Utils::IsAligned(raw_memory, kMaxObjectAlignment));
|
||||
}
|
||||
|
||||
void* object_start() const {
|
||||
@@ -53,7 +53,8 @@ class Image : ValueObject {
|
||||
}
|
||||
|
||||
static constexpr intptr_t kHeaderFields = 2;
|
||||
static const intptr_t kHeaderSize = OS::kMaxPreferredCodeAlignment;
|
||||
static constexpr intptr_t kHeaderSize = kMaxObjectAlignment;
|
||||
COMPILE_ASSERT((kHeaderFields * compiler::target::kWordSize) <= kHeaderSize);
|
||||
|
||||
private:
|
||||
const void* raw_memory_; // The symbol kInstructionsSnapshot.
|
||||
|
||||
@@ -12494,6 +12494,21 @@ const char* Instructions::ToCString() const {
|
||||
return "Instructions";
|
||||
}
|
||||
|
||||
CodeStatistics* Instructions::stats() const {
|
||||
#if defined(DART_PRECOMPILER)
|
||||
return reinterpret_cast<CodeStatistics*>(
|
||||
Thread::Current()->heap()->GetPeer(raw()));
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Instructions::set_stats(CodeStatistics* stats) const {
|
||||
#if defined(DART_PRECOMPILER)
|
||||
Thread::Current()->heap()->SetPeer(raw(), stats);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Encode integer |value| in SLEB128 format and store into |data|.
|
||||
static void EncodeSLEB128(GrowableArray<uint8_t>* data, intptr_t value) {
|
||||
bool is_last_part = false;
|
||||
|
||||
+5
-23
@@ -4782,7 +4782,7 @@ class Instructions : public Object {
|
||||
|
||||
static const intptr_t kMaxElements =
|
||||
(kMaxInt32 - (sizeof(RawInstructions) + sizeof(RawObject) +
|
||||
(2 * OS::kMaxPreferredCodeAlignment)));
|
||||
(2 * kMaxObjectAlignment)));
|
||||
|
||||
static intptr_t InstanceSize() {
|
||||
ASSERT(sizeof(RawInstructions) ==
|
||||
@@ -4791,18 +4791,11 @@ class Instructions : public Object {
|
||||
}
|
||||
|
||||
static intptr_t InstanceSize(intptr_t size) {
|
||||
intptr_t instructions_size =
|
||||
Utils::RoundUp(size, OS::PreferredCodeAlignment());
|
||||
intptr_t result = instructions_size + HeaderSize();
|
||||
ASSERT(result % OS::PreferredCodeAlignment() == 0);
|
||||
return result;
|
||||
return Utils::RoundUp(HeaderSize() + size, kObjectAlignment);
|
||||
}
|
||||
|
||||
static intptr_t HeaderSize() {
|
||||
const intptr_t alignment = OS::PreferredCodeAlignment();
|
||||
const intptr_t aligned_size =
|
||||
Utils::RoundUp(sizeof(RawInstructions), alignment);
|
||||
return aligned_size;
|
||||
return Utils::RoundUp(sizeof(RawInstructions), compiler::target::kWordSize);
|
||||
}
|
||||
|
||||
static RawInstructions* FromPayloadStart(uword payload_start) {
|
||||
@@ -4820,19 +4813,8 @@ class Instructions : public Object {
|
||||
return memcmp(a->ptr(), b->ptr(), InstanceSize(Size(a))) == 0;
|
||||
}
|
||||
|
||||
CodeStatistics* stats() const {
|
||||
#if defined(DART_PRECOMPILER)
|
||||
return raw_ptr()->stats_;
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
void set_stats(CodeStatistics* stats) const {
|
||||
#if defined(DART_PRECOMPILER)
|
||||
StoreNonPointer(&raw_ptr()->stats_, stats);
|
||||
#endif
|
||||
}
|
||||
CodeStatistics* stats() const;
|
||||
void set_stats(CodeStatistics* stats) const;
|
||||
|
||||
uword unchecked_entrypoint_pc_offset() const {
|
||||
return raw_ptr()->unchecked_entrypoint_pc_offset_;
|
||||
|
||||
@@ -67,14 +67,6 @@ class OS {
|
||||
// the platform doesn't care. Guaranteed to be a power of two.
|
||||
static intptr_t ActivationFrameAlignment();
|
||||
|
||||
// This constant is guaranteed to be greater or equal to the
|
||||
// preferred code alignment on all platforms.
|
||||
static const int kMaxPreferredCodeAlignment = 32;
|
||||
|
||||
// Returns the preferred code alignment or zero if
|
||||
// the platform doesn't care. Guaranteed to be a power of two.
|
||||
static intptr_t PreferredCodeAlignment();
|
||||
|
||||
// Returns number of available processor cores.
|
||||
static int NumberOfAvailableProcessors();
|
||||
|
||||
|
||||
@@ -201,25 +201,6 @@ intptr_t OS::ActivationFrameAlignment() {
|
||||
return alignment;
|
||||
}
|
||||
|
||||
intptr_t OS::PreferredCodeAlignment() {
|
||||
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
|
||||
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
|
||||
const int kMinimumAlignment = 32;
|
||||
#elif defined(TARGET_ARCH_ARM)
|
||||
const int kMinimumAlignment = 16;
|
||||
#else
|
||||
#error Unsupported architecture.
|
||||
#endif
|
||||
intptr_t alignment = kMinimumAlignment;
|
||||
// TODO(5411554): Allow overriding default code alignment for
|
||||
// testing purposes.
|
||||
// Flags::DebugIsInt("codealign", &alignment);
|
||||
ASSERT(Utils::IsPowerOfTwo(alignment));
|
||||
ASSERT(alignment >= kMinimumAlignment);
|
||||
ASSERT(alignment <= OS::kMaxPreferredCodeAlignment);
|
||||
return alignment;
|
||||
}
|
||||
|
||||
int OS::NumberOfAvailableProcessors() {
|
||||
return sysconf(_SC_NPROCESSORS_ONLN);
|
||||
}
|
||||
|
||||
@@ -150,25 +150,6 @@ intptr_t OS::ActivationFrameAlignment() {
|
||||
return alignment;
|
||||
}
|
||||
|
||||
intptr_t OS::PreferredCodeAlignment() {
|
||||
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
|
||||
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
|
||||
const int kMinimumAlignment = 32;
|
||||
#elif defined(TARGET_ARCH_ARM)
|
||||
const int kMinimumAlignment = 16;
|
||||
#else
|
||||
#error Unsupported architecture.
|
||||
#endif
|
||||
intptr_t alignment = kMinimumAlignment;
|
||||
// TODO(5411554): Allow overriding default code alignment for
|
||||
// testing purposes.
|
||||
// Flags::DebugIsInt("codealign", &alignment);
|
||||
ASSERT(Utils::IsPowerOfTwo(alignment));
|
||||
ASSERT(alignment >= kMinimumAlignment);
|
||||
ASSERT(alignment <= OS::kMaxPreferredCodeAlignment);
|
||||
return alignment;
|
||||
}
|
||||
|
||||
int OS::NumberOfAvailableProcessors() {
|
||||
return sysconf(_SC_NPROCESSORS_CONF);
|
||||
}
|
||||
|
||||
@@ -513,25 +513,6 @@ intptr_t OS::ActivationFrameAlignment() {
|
||||
return alignment;
|
||||
}
|
||||
|
||||
intptr_t OS::PreferredCodeAlignment() {
|
||||
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
|
||||
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
|
||||
const int kMinimumAlignment = 32;
|
||||
#elif defined(TARGET_ARCH_ARM)
|
||||
const int kMinimumAlignment = 16;
|
||||
#else
|
||||
#error Unsupported architecture.
|
||||
#endif
|
||||
intptr_t alignment = kMinimumAlignment;
|
||||
// TODO(5411554): Allow overriding default code alignment for
|
||||
// testing purposes.
|
||||
// Flags::DebugIsInt("codealign", &alignment);
|
||||
ASSERT(Utils::IsPowerOfTwo(alignment));
|
||||
ASSERT(alignment >= kMinimumAlignment);
|
||||
ASSERT(alignment <= OS::kMaxPreferredCodeAlignment);
|
||||
return alignment;
|
||||
}
|
||||
|
||||
int OS::NumberOfAvailableProcessors() {
|
||||
return sysconf(_SC_NPROCESSORS_ONLN);
|
||||
}
|
||||
|
||||
@@ -151,25 +151,6 @@ intptr_t OS::ActivationFrameAlignment() {
|
||||
#endif // HOST_OS_IOS
|
||||
}
|
||||
|
||||
intptr_t OS::PreferredCodeAlignment() {
|
||||
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
|
||||
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
|
||||
const int kMinimumAlignment = 32;
|
||||
#elif defined(TARGET_ARCH_ARM)
|
||||
const int kMinimumAlignment = 16;
|
||||
#else
|
||||
#error Unsupported architecture.
|
||||
#endif
|
||||
intptr_t alignment = kMinimumAlignment;
|
||||
// TODO(5411554): Allow overriding default code alignment for
|
||||
// testing purposes.
|
||||
// Flags::DebugIsInt("codealign", &alignment);
|
||||
ASSERT(Utils::IsPowerOfTwo(alignment));
|
||||
ASSERT(alignment >= kMinimumAlignment);
|
||||
ASSERT(alignment <= OS::kMaxPreferredCodeAlignment);
|
||||
return alignment;
|
||||
}
|
||||
|
||||
int OS::NumberOfAvailableProcessors() {
|
||||
return sysconf(_SC_NPROCESSORS_ONLN);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ VM_UNIT_TEST_CASE_WITH_EXPECTATION(SNPrint_BadArgs, "Crash") {
|
||||
|
||||
VM_UNIT_TEST_CASE(OsFuncs) {
|
||||
EXPECT(Utils::IsPowerOfTwo(OS::ActivationFrameAlignment()));
|
||||
EXPECT(Utils::IsPowerOfTwo(OS::PreferredCodeAlignment()));
|
||||
int procs = OS::NumberOfAvailableProcessors();
|
||||
EXPECT_LE(1, procs);
|
||||
}
|
||||
|
||||
@@ -190,18 +190,6 @@ intptr_t OS::ActivationFrameAlignment() {
|
||||
#endif
|
||||
}
|
||||
|
||||
intptr_t OS::PreferredCodeAlignment() {
|
||||
ASSERT(32 <= OS::kMaxPreferredCodeAlignment);
|
||||
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
|
||||
defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_DBC)
|
||||
return 32;
|
||||
#elif defined(TARGET_ARCH_ARM)
|
||||
return 16;
|
||||
#else
|
||||
#error Unsupported architecture.
|
||||
#endif
|
||||
}
|
||||
|
||||
int OS::NumberOfAvailableProcessors() {
|
||||
SYSTEM_INFO info;
|
||||
GetSystemInfo(&info);
|
||||
|
||||
@@ -51,6 +51,10 @@ static constexpr intptr_t kObjectAlignmentLog2 =
|
||||
static constexpr intptr_t kObjectAlignmentMask =
|
||||
HostObjectAlignment::kObjectAlignmentMask;
|
||||
|
||||
// The largest value of kObjectAlignment across all configurations.
|
||||
static constexpr intptr_t kMaxObjectAlignment = 16;
|
||||
COMPILE_ASSERT(kMaxObjectAlignment >= kObjectAlignment);
|
||||
|
||||
// On all targets heap pointers are tagged by set least significant bit.
|
||||
//
|
||||
// To recover address of the actual heap object kHeapObjectTag needs to be
|
||||
|
||||
@@ -1478,15 +1478,6 @@ class RawInstructions : public RawObject {
|
||||
uint32_t size_and_flags_;
|
||||
uint32_t unchecked_entrypoint_pc_offset_;
|
||||
|
||||
// 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_;
|
||||
|
||||
// Variable length data follows here.
|
||||
uint8_t* data() { OPEN_ARRAY_START(uint8_t, uint8_t); }
|
||||
|
||||
|
||||
@@ -199,7 +199,7 @@ class Snapshot {
|
||||
if (!IncludesCode(kind())) {
|
||||
return NULL;
|
||||
}
|
||||
uword offset = Utils::RoundUp(length(), OS::kMaxPreferredCodeAlignment);
|
||||
uword offset = Utils::RoundUp(length(), kMaxObjectAlignment);
|
||||
return Addr() + offset;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user