mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 21:40:07 +00:00
[vm] Fix various UBSan failures.
Bug: https://github.com/dart-lang/sdk/issues/39427 Change-Id: I74e0eee623d88005fb2893d03e284a87daa09260 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/146696 Reviewed-by: Alexander Markov <alexmarkov@google.com> Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
parent
8c79102889
commit
2707880f1b
|
@ -484,7 +484,7 @@ int64_t File::LengthFromPath(Namespace* namespc, const char* name) {
|
|||
static void MillisecondsToTimespec(int64_t millis, struct timespec* t) {
|
||||
ASSERT(t != NULL);
|
||||
t->tv_sec = millis / kMillisecondsPerSecond;
|
||||
t->tv_nsec = (millis - (t->tv_sec * kMillisecondsPerSecond)) * 1000L;
|
||||
t->tv_nsec = (millis % kMillisecondsPerSecond) * 1000L;
|
||||
}
|
||||
|
||||
void File::Stat(Namespace* namespc, const char* name, int64_t* data) {
|
||||
|
|
|
@ -480,7 +480,7 @@ static int64_t TimespecToMilliseconds(const struct timespec& t) {
|
|||
static void MillisecondsToTimespec(int64_t millis, struct timespec* t) {
|
||||
ASSERT(t != NULL);
|
||||
t->tv_sec = millis / kMillisecondsPerSecond;
|
||||
t->tv_nsec = (millis - (t->tv_sec * kMillisecondsPerSecond)) * 1000L;
|
||||
t->tv_nsec = (millis % kMillisecondsPerSecond) * 1000L;
|
||||
}
|
||||
|
||||
void File::Stat(Namespace* namespc, const char* name, int64_t* data) {
|
||||
|
|
|
@ -489,7 +489,7 @@ static int64_t TimespecToMilliseconds(const struct timespec& t) {
|
|||
static void MillisecondsToTimespec(int64_t millis, struct timespec* t) {
|
||||
ASSERT(t != NULL);
|
||||
t->tv_sec = millis / kMillisecondsPerSecond;
|
||||
t->tv_nsec = (millis - (t->tv_sec * kMillisecondsPerSecond)) * 1000L;
|
||||
t->tv_nsec = (millis % kMillisecondsPerSecond) * 1000L;
|
||||
}
|
||||
|
||||
void File::Stat(Namespace* namespc, const char* name, int64_t* data) {
|
||||
|
|
|
@ -123,12 +123,12 @@ void TestSet(IntKeyHash hash, int size) {
|
|||
EXPECT_EQ(0u, set.occupancy());
|
||||
|
||||
// Insert a long series of values.
|
||||
const int start = 453;
|
||||
const int factor = 13;
|
||||
const int offset = 7;
|
||||
const uint32_t start = 453;
|
||||
const uint32_t factor = 13;
|
||||
const uint32_t offset = 7;
|
||||
const uint32_t n = size;
|
||||
|
||||
int x = start;
|
||||
uint32_t x = start;
|
||||
for (uint32_t i = 0; i < n; i++) {
|
||||
EXPECT_EQ(i, set.occupancy());
|
||||
set.Insert(x);
|
||||
|
|
|
@ -6,6 +6,14 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(__GNUC__) || defined(__Clang__)
|
||||
__attribute__((no_sanitize("undefined")))
|
||||
#endif
|
||||
void Crash() {
|
||||
int* segfault = NULL;
|
||||
*segfault = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Run ./process_test <outstream> <echocount> <exitcode> <crash>
|
||||
* <outstream>: 0 = stdout, 1 = stderr, 2 = stdout and stderr
|
||||
|
@ -32,8 +40,7 @@ int main(int argc, char* argv[]) {
|
|||
int crash = atoi(argv[4]);
|
||||
|
||||
if (crash == 1) {
|
||||
int* segfault = NULL;
|
||||
*segfault = 1;
|
||||
Crash();
|
||||
}
|
||||
|
||||
const int kLineSize = 128;
|
||||
|
|
|
@ -89,8 +89,8 @@ DEFINE_NATIVE_ENTRY(Double_hashCode, 0, 1) {
|
|||
if (FLAG_trace_intrinsified_natives) {
|
||||
OS::PrintErr("Double_hashCode %f\n", val);
|
||||
}
|
||||
if (val >= static_cast<double>(kMinInt64) &&
|
||||
val <= static_cast<double>(kMaxInt64)) {
|
||||
if ((val >= kMinInt64RepresentableAsDouble) &&
|
||||
(val <= kMaxInt64RepresentableAsDouble)) {
|
||||
int64_t ival = static_cast<int64_t>(val);
|
||||
if (static_cast<double>(ival) == val) {
|
||||
return Integer::New(ival);
|
||||
|
|
|
@ -459,6 +459,8 @@ const int32_t kMaxInt32 = 0x7FFFFFFF;
|
|||
const uint32_t kMaxUint32 = 0xFFFFFFFF;
|
||||
const int64_t kMinInt64 = DART_INT64_C(0x8000000000000000);
|
||||
const int64_t kMaxInt64 = DART_INT64_C(0x7FFFFFFFFFFFFFFF);
|
||||
const int64_t kMinInt64RepresentableAsDouble = kMinInt64;
|
||||
const int64_t kMaxInt64RepresentableAsDouble = DART_INT64_C(0x7FFFFFFFFFFFFC00);
|
||||
const uint64_t kMaxUint64 = DART_2PART_UINT64_C(0xFFFFFFFF, FFFFFFFF);
|
||||
const int64_t kSignBitDouble = DART_INT64_C(0x8000000000000000);
|
||||
|
||||
|
@ -636,36 +638,6 @@ inline D bit_copy(const S& source) {
|
|||
return destination;
|
||||
}
|
||||
|
||||
#if defined(HOST_ARCH_ARM) || defined(HOST_ARCH_ARM64)
|
||||
// Similar to bit_copy and bit_cast, but does take the type from the argument.
|
||||
template <typename T>
|
||||
static inline T ReadUnaligned(const T* ptr) {
|
||||
T value;
|
||||
memcpy(reinterpret_cast<void*>(&value), reinterpret_cast<const void*>(ptr),
|
||||
sizeof(value));
|
||||
return value;
|
||||
}
|
||||
|
||||
// Similar to bit_copy and bit_cast, but does take the type from the argument.
|
||||
template <typename T>
|
||||
static inline void StoreUnaligned(T* ptr, T value) {
|
||||
memcpy(reinterpret_cast<void*>(ptr), reinterpret_cast<const void*>(&value),
|
||||
sizeof(value));
|
||||
}
|
||||
#else // !(HOST_ARCH_ARM || HOST_ARCH_ARM64)
|
||||
// Similar to bit_copy and bit_cast, but does take the type from the argument.
|
||||
template <typename T>
|
||||
static inline T ReadUnaligned(const T* ptr) {
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
// Similar to bit_copy and bit_cast, but does take the type from the argument.
|
||||
template <typename T>
|
||||
static inline void StoreUnaligned(T* ptr, T value) {
|
||||
*ptr = value;
|
||||
}
|
||||
#endif // !(HOST_ARCH_ARM || HOST_ARCH_ARM64)
|
||||
|
||||
// On Windows the reentrent version of strtok is called
|
||||
// strtok_s. Unify on the posix name strtok_r.
|
||||
#if defined(HOST_OS_WINDOWS)
|
||||
|
|
|
@ -205,6 +205,9 @@ class BaseGrowableArray : public B {
|
|||
template <typename T, typename B, typename Allocator>
|
||||
inline void BaseGrowableArray<T, B, Allocator>::Sort(int compare(const T*,
|
||||
const T*)) {
|
||||
// Avoid calling qsort with a null array.
|
||||
if (length_ == 0) return;
|
||||
|
||||
typedef int (*CompareFunction)(const void*, const void*);
|
||||
qsort(data_, length_, sizeof(T), reinterpret_cast<CompareFunction>(compare));
|
||||
}
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
#ifndef RUNTIME_PLATFORM_SAFE_STACK_H_
|
||||
#define RUNTIME_PLATFORM_SAFE_STACK_H_
|
||||
|
||||
#include "platform/globals.h"
|
||||
|
||||
#if defined(__has_feature)
|
||||
#if __has_feature(safe_stack)
|
||||
#define USING_SAFE_STACK
|
||||
|
|
43
runtime/platform/unaligned.h
Normal file
43
runtime/platform/unaligned.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
// Copyright (c) 2020, 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_PLATFORM_UNALIGNED_H_
|
||||
#define RUNTIME_PLATFORM_UNALIGNED_H_
|
||||
|
||||
#include "platform/globals.h"
|
||||
#include "platform/undefined_behavior_sanitizer.h"
|
||||
|
||||
namespace dart {
|
||||
|
||||
#if defined(HOST_ARCH_ARM) || defined(HOST_ARCH_ARM64)
|
||||
template <typename T>
|
||||
static inline T LoadUnaligned(const T* ptr) {
|
||||
T value;
|
||||
memcpy(reinterpret_cast<void*>(&value), reinterpret_cast<const void*>(ptr),
|
||||
sizeof(value));
|
||||
return value;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline void StoreUnaligned(T* ptr, T value) {
|
||||
memcpy(reinterpret_cast<void*>(ptr), reinterpret_cast<const void*>(&value),
|
||||
sizeof(value));
|
||||
}
|
||||
#else // !(HOST_ARCH_ARM || HOST_ARCH_ARM64)
|
||||
template <typename T>
|
||||
NO_SANITIZE_UNDEFINED("alignment")
|
||||
static inline T LoadUnaligned(const T* ptr) {
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
NO_SANITIZE_UNDEFINED("alignment")
|
||||
static inline void StoreUnaligned(T* ptr, T value) {
|
||||
*ptr = value;
|
||||
}
|
||||
#endif // !(HOST_ARCH_ARM || HOST_ARCH_ARM64)
|
||||
|
||||
} // namespace dart
|
||||
|
||||
#endif // RUNTIME_PLATFORM_UNALIGNED_H_
|
20
runtime/platform/undefined_behavior_sanitizer.h
Normal file
20
runtime/platform/undefined_behavior_sanitizer.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) 2020, 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_PLATFORM_UNDEFINED_BEHAVIOR_SANITIZER_H_
|
||||
#define RUNTIME_PLATFORM_UNDEFINED_BEHAVIOR_SANITIZER_H_
|
||||
|
||||
#if defined(__has_feature)
|
||||
#if __has_feature(undefined_behavior_sanitizer)
|
||||
#define USING_UNDEFINED_BEHAVIOR_SANITIZER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(USING_UNDEFINED_BEHAVIOR_SANITIZER)
|
||||
#define NO_SANITIZE_UNDEFINED(check) __attribute__((no_sanitize(check)))
|
||||
#else
|
||||
#define NO_SANITIZE_UNDEFINED(check)
|
||||
#endif
|
||||
|
||||
#endif // RUNTIME_PLATFORM_UNDEFINED_BEHAVIOR_SANITIZER_H_
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "platform/allocation.h"
|
||||
#include "platform/globals.h"
|
||||
#include "platform/unaligned.h"
|
||||
|
||||
namespace dart {
|
||||
|
||||
|
@ -132,9 +133,9 @@ class Utf16 : AllStatic {
|
|||
// Returns the character at i and advances i to the next character
|
||||
// boundary.
|
||||
static int32_t Next(const uint16_t* characters, intptr_t* i, intptr_t len) {
|
||||
int32_t ch = characters[*i];
|
||||
int32_t ch = LoadUnaligned(&characters[*i]);
|
||||
if (Utf16::IsLeadSurrogate(ch) && (*i < (len - 1))) {
|
||||
int32_t ch2 = characters[*i + 1];
|
||||
int32_t ch2 = LoadUnaligned(&characters[*i + 1]);
|
||||
if (Utf16::IsTrailSurrogate(ch2)) {
|
||||
ch = Utf16::Decode(ch, ch2);
|
||||
*i += 1;
|
||||
|
|
|
@ -215,7 +215,7 @@ class Utils {
|
|||
}
|
||||
|
||||
static inline int64_t LowHighTo64Bits(uint32_t low, int32_t high) {
|
||||
return (static_cast<int64_t>(high) << 32) | (low & 0x0ffffffffLL);
|
||||
return (static_cast<uint64_t>(high) << 32) | (low & 0x0ffffffffLL);
|
||||
}
|
||||
|
||||
static inline constexpr bool IsAlphaNumeric(uint32_t c) {
|
||||
|
@ -347,7 +347,7 @@ class Utils {
|
|||
"Unexpected uword size");
|
||||
return std::numeric_limits<uword>::max();
|
||||
}
|
||||
return (1ll << n) - 1;
|
||||
return (static_cast<uword>(1) << n) - 1;
|
||||
}
|
||||
|
||||
static word SignedNBitMask(uint32_t n) {
|
||||
|
@ -373,22 +373,22 @@ class Utils {
|
|||
static ValueType DecodeSLEB128(const uint8_t* data,
|
||||
const intptr_t data_length,
|
||||
intptr_t* byte_index) {
|
||||
using Unsigned = typename std::make_unsigned<ValueType>::type;
|
||||
ASSERT(*byte_index < data_length);
|
||||
uword shift = 0;
|
||||
ValueType value = 0;
|
||||
Unsigned value = 0;
|
||||
uint8_t part = 0;
|
||||
do {
|
||||
part = data[(*byte_index)++];
|
||||
value |= static_cast<ValueType>(part & 0x7f) << shift;
|
||||
value |= static_cast<Unsigned>(part & 0x7f) << shift;
|
||||
shift += 7;
|
||||
} while ((part & 0x80) != 0);
|
||||
|
||||
if ((shift < (sizeof(ValueType) * CHAR_BIT)) && ((part & 0x40) != 0)) {
|
||||
using Unsigned = typename std::make_unsigned<ValueType>::type;
|
||||
const Unsigned kMax = std::numeric_limits<Unsigned>::max();
|
||||
value |= static_cast<ValueType>(kMax << shift);
|
||||
value |= static_cast<Unsigned>(kMax << shift);
|
||||
}
|
||||
return value;
|
||||
return static_cast<ValueType>(value);
|
||||
}
|
||||
|
||||
static char* StrError(int err, char* buffer, size_t bufsize);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
|
||||
#if defined(TARGET_ARCH_IA32)
|
||||
|
||||
#include "platform/unaligned.h"
|
||||
#include "vm/code_patcher.h"
|
||||
#include "vm/cpu.h"
|
||||
#include "vm/dart_entry.h"
|
||||
|
@ -89,21 +90,18 @@ class InstanceCall : public UnoptimizedCall {
|
|||
#endif // DEBUG
|
||||
}
|
||||
|
||||
ObjectPtr data() const { return *reinterpret_cast<ObjectPtr*>(start_ + 1); }
|
||||
ObjectPtr data() const {
|
||||
return LoadUnaligned(reinterpret_cast<ObjectPtr*>(start_ + 1));
|
||||
}
|
||||
void set_data(const Object& data) const {
|
||||
uword* cache_addr = reinterpret_cast<uword*>(start_ + 1);
|
||||
uword imm = static_cast<uword>(data.raw());
|
||||
*cache_addr = imm;
|
||||
StoreUnaligned(reinterpret_cast<ObjectPtr*>(start_ + 1), data.raw());
|
||||
}
|
||||
|
||||
CodePtr target() const {
|
||||
const uword imm = *reinterpret_cast<uword*>(start_ + 6);
|
||||
return static_cast<CodePtr>(imm);
|
||||
return LoadUnaligned(reinterpret_cast<CodePtr*>(start_ + 6));
|
||||
}
|
||||
void set_target(const Code& target) const {
|
||||
uword* target_addr = reinterpret_cast<uword*>(start_ + 6);
|
||||
uword imm = static_cast<uword>(target.raw());
|
||||
*target_addr = imm;
|
||||
StoreUnaligned(reinterpret_cast<CodePtr*>(start_ + 6), target.raw());
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -179,7 +179,7 @@ class PatchCodeWithHandle : public AssemblerFixup {
|
|||
// Patch the handle into the code. Once the instructions are installed into
|
||||
// a raw code object and the pointer offsets are setup, the handle is
|
||||
// resolved.
|
||||
region.Store<const Object*>(position, &object_);
|
||||
region.StoreUnaligned<const Object*>(position, &object_);
|
||||
pointer_offsets_->Add(position);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#endif // defined(DART_PRECOMPILED_RUNTIME)
|
||||
|
||||
#include "platform/assert.h"
|
||||
#include "platform/unaligned.h"
|
||||
#include "vm/allocation.h"
|
||||
#include "vm/compiler/assembler/object_pool_builder.h"
|
||||
#include "vm/compiler/runtime_api.h"
|
||||
|
@ -164,7 +165,13 @@ class AssemblerBuffer : public ValueObject {
|
|||
template <typename T>
|
||||
void Emit(T value) {
|
||||
ASSERT(HasEnsuredCapacity());
|
||||
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
|
||||
// Variable-length instructions in ia32/x64 have unaligned immediates.
|
||||
StoreUnaligned(reinterpret_cast<T*>(cursor_), value);
|
||||
#else
|
||||
// Other architecture have aligned, fixed-length instructions.
|
||||
*reinterpret_cast<T*>(cursor_) = value;
|
||||
#endif
|
||||
cursor_ += sizeof(T);
|
||||
}
|
||||
|
||||
|
@ -181,14 +188,26 @@ class AssemblerBuffer : public ValueObject {
|
|||
T Load(intptr_t position) {
|
||||
ASSERT(position >= 0 &&
|
||||
position <= (Size() - static_cast<intptr_t>(sizeof(T))));
|
||||
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
|
||||
// Variable-length instructions in ia32/x64 have unaligned immediates.
|
||||
return LoadUnaligned(reinterpret_cast<T*>(contents_ + position));
|
||||
#else
|
||||
// Other architecture have aligned, fixed-length instructions.
|
||||
return *reinterpret_cast<T*>(contents_ + position);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Store(intptr_t position, T value) {
|
||||
ASSERT(position >= 0 &&
|
||||
position <= (Size() - static_cast<intptr_t>(sizeof(T))));
|
||||
#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
|
||||
// Variable-length instructions in ia32/x64 have unaligned immediates.
|
||||
StoreUnaligned(reinterpret_cast<T*>(contents_ + position), value);
|
||||
#else
|
||||
// Other architecture have aligned, fixed-length instructions.
|
||||
*reinterpret_cast<T*>(contents_ + position) = value;
|
||||
#endif
|
||||
}
|
||||
|
||||
const ZoneGrowableArray<intptr_t>& pointer_offsets() const {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "vm/compiler/assembler/disassembler.h"
|
||||
|
||||
#include "platform/unaligned.h"
|
||||
#include "vm/code_patcher.h"
|
||||
#include "vm/deopt_instructions.h"
|
||||
#include "vm/globals.h"
|
||||
|
@ -232,7 +233,7 @@ void Disassembler::DisassembleCodeHelper(const char* function_fullname,
|
|||
Object& obj = Object::Handle(zone);
|
||||
for (intptr_t i = code.pointer_offsets_length() - 1; i >= 0; i--) {
|
||||
const uword addr = code.GetPointerOffsetAt(i) + code.PayloadStart();
|
||||
obj = *reinterpret_cast<ObjectPtr*>(addr);
|
||||
obj = LoadUnaligned(reinterpret_cast<ObjectPtr*>(addr));
|
||||
THR_Print(" %d : %#" Px " '%s'\n", code.GetPointerOffsetAt(i), addr,
|
||||
obj.ToCString());
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "vm/compiler/assembler/disassembler.h"
|
||||
|
||||
#include "platform/unaligned.h"
|
||||
#include "platform/utils.h"
|
||||
#include "vm/allocation.h"
|
||||
#include "vm/constants_x86.h"
|
||||
|
@ -403,7 +404,7 @@ int DisassemblerX64::PrintRightOperandHelper(
|
|||
switch (mod) {
|
||||
case 0:
|
||||
if ((rm & 7) == 5) {
|
||||
int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 1);
|
||||
int32_t disp = LoadUnaligned(reinterpret_cast<int32_t*>(modrmp + 1));
|
||||
Print("[rip");
|
||||
PrintDisp(disp, "]");
|
||||
return 5;
|
||||
|
@ -419,7 +420,7 @@ int DisassemblerX64::PrintRightOperandHelper(
|
|||
return 2;
|
||||
} else if (base == 5) {
|
||||
// base == rbp means no base register (when mod == 0).
|
||||
int32_t disp = *reinterpret_cast<int32_t*>(modrmp + 2);
|
||||
int32_t disp = LoadUnaligned(reinterpret_cast<int32_t*>(modrmp + 2));
|
||||
Print("[%s*%d", NameOfCPURegister(index), 1 << scale);
|
||||
PrintDisp(disp, "]");
|
||||
return 6;
|
||||
|
@ -444,8 +445,9 @@ int DisassemblerX64::PrintRightOperandHelper(
|
|||
uint8_t sib = *(modrmp + 1);
|
||||
int scale, index, base;
|
||||
get_sib(sib, &scale, &index, &base);
|
||||
int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 2)
|
||||
: *reinterpret_cast<int8_t*>(modrmp + 2);
|
||||
int disp = (mod == 2)
|
||||
? LoadUnaligned(reinterpret_cast<int32_t*>(modrmp + 2))
|
||||
: *reinterpret_cast<int8_t*>(modrmp + 2);
|
||||
if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) {
|
||||
Print("[%s", NameOfCPURegister(base));
|
||||
PrintDisp(disp, "]");
|
||||
|
@ -457,8 +459,9 @@ int DisassemblerX64::PrintRightOperandHelper(
|
|||
return mod == 2 ? 6 : 3;
|
||||
} else {
|
||||
// No sib.
|
||||
int disp = (mod == 2) ? *reinterpret_cast<int32_t*>(modrmp + 1)
|
||||
: *reinterpret_cast<int8_t*>(modrmp + 1);
|
||||
int disp = (mod == 2)
|
||||
? LoadUnaligned(reinterpret_cast<int32_t*>(modrmp + 1))
|
||||
: *reinterpret_cast<int8_t*>(modrmp + 1);
|
||||
Print("[%s", NameOfCPURegister(rm));
|
||||
PrintDisp(disp, "]");
|
||||
return (mod == 2) ? 5 : 2;
|
||||
|
@ -490,18 +493,18 @@ int DisassemblerX64::PrintImmediate(uint8_t* data,
|
|||
break;
|
||||
case WORD_SIZE:
|
||||
if (sign_extend) {
|
||||
value = *reinterpret_cast<int16_t*>(data);
|
||||
value = LoadUnaligned(reinterpret_cast<int16_t*>(data));
|
||||
} else {
|
||||
value = *reinterpret_cast<uint16_t*>(data);
|
||||
value = LoadUnaligned(reinterpret_cast<uint16_t*>(data));
|
||||
}
|
||||
count = 2;
|
||||
break;
|
||||
case DOUBLEWORD_SIZE:
|
||||
case QUADWORD_SIZE:
|
||||
if (sign_extend) {
|
||||
value = *reinterpret_cast<int32_t*>(data);
|
||||
value = LoadUnaligned(reinterpret_cast<int32_t*>(data));
|
||||
} else {
|
||||
value = *reinterpret_cast<uint32_t*>(data);
|
||||
value = LoadUnaligned(reinterpret_cast<uint32_t*>(data));
|
||||
}
|
||||
count = 4;
|
||||
break;
|
||||
|
@ -525,21 +528,21 @@ void DisassemblerX64::PrintImmediateValue(int64_t value,
|
|||
if (byte_count == 1) {
|
||||
int8_t v8 = static_cast<int8_t>(value);
|
||||
if (v8 < 0 && signed_value) {
|
||||
Print("-%#" Px32, static_cast<int8_t>(-v8));
|
||||
Print("-%#" Px32, -static_cast<uint8_t>(v8));
|
||||
} else {
|
||||
Print("%#" Px32, static_cast<uint8_t>(v8));
|
||||
}
|
||||
} else if (byte_count == 2) {
|
||||
int16_t v16 = static_cast<int16_t>(value);
|
||||
if (v16 < 0 && signed_value) {
|
||||
Print("-%#" Px32, static_cast<int16_t>(-v16));
|
||||
Print("-%#" Px32, -static_cast<uint16_t>(v16));
|
||||
} else {
|
||||
Print("%#" Px32, static_cast<uint16_t>(v16));
|
||||
}
|
||||
} else if (byte_count == 4) {
|
||||
int32_t v32 = static_cast<int32_t>(value);
|
||||
if (v32 < 0 && signed_value) {
|
||||
Print("-%#010" Px32, static_cast<int32_t>(-v32));
|
||||
Print("-%#010" Px32, -static_cast<uint32_t>(v32));
|
||||
} else {
|
||||
if (v32 > 0xffff) {
|
||||
Print("%#010" Px32, v32);
|
||||
|
@ -550,7 +553,7 @@ void DisassemblerX64::PrintImmediateValue(int64_t value,
|
|||
} else if (byte_count == 8) {
|
||||
int64_t v64 = static_cast<int64_t>(value);
|
||||
if (v64 < 0 && signed_value) {
|
||||
Print("-%#018" Px64, static_cast<int64_t>(-v64));
|
||||
Print("-%#018" Px64, -static_cast<uint64_t>(v64));
|
||||
} else {
|
||||
if (v64 > 0xffffffffll) {
|
||||
Print("%#018" Px64, v64);
|
||||
|
@ -778,7 +781,8 @@ void DisassemblerX64::PrintJump(uint8_t* pc, int32_t disp) {
|
|||
if (FLAG_disassemble_relative) {
|
||||
Print("%+d", disp);
|
||||
} else {
|
||||
PrintAddress(pc + disp);
|
||||
PrintAddress(
|
||||
reinterpret_cast<uint8_t*>(reinterpret_cast<uintptr_t>(pc) + disp));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -810,7 +814,7 @@ int DisassemblerX64::JumpShort(uint8_t* data) {
|
|||
int DisassemblerX64::JumpConditional(uint8_t* data) {
|
||||
ASSERT(0x0F == *data);
|
||||
uint8_t cond = *(data + 1) & 0x0F;
|
||||
int32_t disp = *reinterpret_cast<int32_t*>(data + 2) + 6;
|
||||
int32_t disp = LoadUnaligned(reinterpret_cast<int32_t*>(data + 2)) + 6;
|
||||
const char* mnem = conditional_code_suffix[cond];
|
||||
Print("j%s ", mnem);
|
||||
PrintJump(data, disp);
|
||||
|
@ -1178,15 +1182,15 @@ bool DisassemblerX64::DecodeInstructionType(uint8_t** data) {
|
|||
int imm_bytes = 0;
|
||||
switch (operand_size()) {
|
||||
case WORD_SIZE:
|
||||
addr = *reinterpret_cast<int16_t*>(*data + 1);
|
||||
addr = LoadUnaligned(reinterpret_cast<int16_t*>(*data + 1));
|
||||
imm_bytes = 2;
|
||||
break;
|
||||
case DOUBLEWORD_SIZE:
|
||||
addr = *reinterpret_cast<int32_t*>(*data + 1);
|
||||
addr = LoadUnaligned(reinterpret_cast<int32_t*>(*data + 1));
|
||||
imm_bytes = 4;
|
||||
break;
|
||||
case QUADWORD_SIZE:
|
||||
addr = *reinterpret_cast<int64_t*>(*data + 1);
|
||||
addr = LoadUnaligned(reinterpret_cast<int64_t*>(*data + 1));
|
||||
imm_bytes = 8;
|
||||
break;
|
||||
default:
|
||||
|
@ -1200,7 +1204,7 @@ bool DisassemblerX64::DecodeInstructionType(uint8_t** data) {
|
|||
}
|
||||
|
||||
case CALL_JUMP_INSTR: {
|
||||
int32_t disp = *reinterpret_cast<int32_t*>(*data + 1) + 5;
|
||||
int32_t disp = LoadUnaligned(reinterpret_cast<int32_t*>(*data + 1)) + 5;
|
||||
Print("%s ", idesc.mnem);
|
||||
PrintJump(*data, disp);
|
||||
(*data) += 5;
|
||||
|
@ -1635,8 +1639,9 @@ int DisassemblerX64::InstructionDecode(uword pc) {
|
|||
case 0x6B: {
|
||||
int mod, regop, rm;
|
||||
get_modrm(*(data + 1), &mod, ®op, &rm);
|
||||
int32_t imm =
|
||||
*data == 0x6B ? *(data + 2) : *reinterpret_cast<int32_t*>(data + 2);
|
||||
int32_t imm = *data == 0x6B
|
||||
? *(data + 2)
|
||||
: LoadUnaligned(reinterpret_cast<int32_t*>(data + 2));
|
||||
Print("imul%s %s,%s,", operand_size_code(), NameOfCPURegister(regop),
|
||||
NameOfCPURegister(rm));
|
||||
PrintImmediateValue(imm);
|
||||
|
@ -1800,7 +1805,8 @@ int DisassemblerX64::InstructionDecode(uword pc) {
|
|||
}
|
||||
case 0x68:
|
||||
Print("push ");
|
||||
PrintImmediateValue(*reinterpret_cast<int32_t*>(data + 1));
|
||||
PrintImmediateValue(
|
||||
LoadUnaligned(reinterpret_cast<int32_t*>(data + 1)));
|
||||
data += 5;
|
||||
break;
|
||||
|
||||
|
@ -1995,7 +2001,8 @@ void Disassembler::DecodeInstruction(char* hex_buffer,
|
|||
for (intptr_t i = 0; i < offsets_length; i++) {
|
||||
uword addr = code.GetPointerOffsetAt(i) + code.PayloadStart();
|
||||
if ((pc <= addr) && (addr < (pc + instruction_length))) {
|
||||
*object = &Object::Handle(*reinterpret_cast<ObjectPtr*>(addr));
|
||||
*object =
|
||||
&Object::Handle(LoadUnaligned(reinterpret_cast<ObjectPtr*>(addr)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,8 @@ intptr_t RegisterSet::RegisterCount(intptr_t registers) {
|
|||
intptr_t count = 0;
|
||||
while (registers != 0) {
|
||||
++count;
|
||||
registers &= (registers - 1); // Clear the least significant bit set.
|
||||
// Clear the least significant bit set.
|
||||
registers &= (static_cast<uintptr_t>(registers) - 1);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ class Location : public ValueObject {
|
|||
// Note that two locations with different kinds should never point to
|
||||
// the same place. For example kQuadStackSlot location should never intersect
|
||||
// with kDoubleStackSlot location.
|
||||
enum Kind {
|
||||
enum Kind : intptr_t {
|
||||
// This location is invalid. Payload must be zero.
|
||||
kInvalid = 0,
|
||||
|
||||
|
|
|
@ -1827,7 +1827,7 @@ RangeBoundary RangeBoundary::Shl(const RangeBoundary& value_boundary,
|
|||
} else if (shift_count == 0 ||
|
||||
(limit > 0 && Utils::IsInt(static_cast<int>(limit), value))) {
|
||||
// Result stays in 64 bit range.
|
||||
const int64_t result = value << shift_count;
|
||||
const int64_t result = static_cast<uint64_t>(value) << shift_count;
|
||||
return RangeBoundary(result);
|
||||
}
|
||||
|
||||
|
|
|
@ -277,7 +277,7 @@ class FunctionNodeHelper {
|
|||
kEnd,
|
||||
};
|
||||
|
||||
enum AsyncMarker {
|
||||
enum AsyncMarker : intptr_t {
|
||||
kSync = 0,
|
||||
kSyncStar = 1,
|
||||
kAsync = 2,
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include <memory>
|
||||
|
||||
#include "vm/dart_api_message.h"
|
||||
|
||||
#include "platform/undefined_behavior_sanitizer.h"
|
||||
#include "platform/unicode.h"
|
||||
#include "vm/object.h"
|
||||
#include "vm/snapshot_ids.h"
|
||||
|
@ -102,8 +104,6 @@ Dart_CObject* ApiMessageReader::AllocateDartCObjectInt64(int64_t val) {
|
|||
return value;
|
||||
}
|
||||
|
||||
_Dart_CObject* ApiMessageReader::singleton_uint32_typed_data_ = NULL;
|
||||
|
||||
Dart_CObject* ApiMessageReader::AllocateDartCObjectDouble(double val) {
|
||||
Dart_CObject* value = AllocateDartCObject(Dart_CObject_kDouble);
|
||||
value->value.as_double = val;
|
||||
|
@ -789,6 +789,8 @@ ApiMessageWriter::~ApiMessageWriter() {
|
|||
delete finalizable_data_;
|
||||
}
|
||||
|
||||
NO_SANITIZE_UNDEFINED(
|
||||
"enum") // TODO(https://github.com/dart-lang/sdk/issues/39427)
|
||||
void ApiMessageWriter::MarkCObject(Dart_CObject* object, intptr_t object_id) {
|
||||
// Mark the object as serialized by adding the object id to the
|
||||
// upper bits of the type field in the Dart_CObject structure. Add
|
||||
|
@ -799,16 +801,22 @@ void ApiMessageWriter::MarkCObject(Dart_CObject* object, intptr_t object_id) {
|
|||
((mark_value) << kDartCObjectTypeBits) | object->type);
|
||||
}
|
||||
|
||||
NO_SANITIZE_UNDEFINED(
|
||||
"enum") // TODO(https://github.com/dart-lang/sdk/issues/39427)
|
||||
void ApiMessageWriter::UnmarkCObject(Dart_CObject* object) {
|
||||
ASSERT(IsCObjectMarked(object));
|
||||
object->type =
|
||||
static_cast<Dart_CObject_Type>(object->type & kDartCObjectTypeMask);
|
||||
}
|
||||
|
||||
NO_SANITIZE_UNDEFINED(
|
||||
"enum") // TODO(https://github.com/dart-lang/sdk/issues/39427)
|
||||
bool ApiMessageWriter::IsCObjectMarked(Dart_CObject* object) {
|
||||
return (object->type & kDartCObjectMarkMask) != 0;
|
||||
}
|
||||
|
||||
NO_SANITIZE_UNDEFINED(
|
||||
"enum") // TODO(https://github.com/dart-lang/sdk/issues/39427)
|
||||
intptr_t ApiMessageWriter::GetMarkedCObjectMark(Dart_CObject* object) {
|
||||
ASSERT(IsCObjectMarked(object));
|
||||
intptr_t mark_value =
|
||||
|
@ -954,6 +962,8 @@ bool ApiMessageWriter::WriteCObjectRef(Dart_CObject* object) {
|
|||
return WriteCObjectInlined(object, type);
|
||||
}
|
||||
|
||||
NO_SANITIZE_UNDEFINED(
|
||||
"enum") // TODO(https://github.com/dart-lang/sdk/issues/39427)
|
||||
bool ApiMessageWriter::WriteForwardedCObject(Dart_CObject* object) {
|
||||
ASSERT(IsCObjectMarked(object));
|
||||
Dart_CObject_Type type =
|
||||
|
|
|
@ -148,8 +148,6 @@ class ApiMessageReader : public BaseReader {
|
|||
Dart_CObject dynamic_type_marker;
|
||||
|
||||
MessageFinalizableData* finalizable_data_;
|
||||
|
||||
static _Dart_CObject* singleton_uint32_typed_data_;
|
||||
};
|
||||
|
||||
class ApiMessageWriter : public BaseWriter {
|
||||
|
|
|
@ -68,7 +68,9 @@ class ReadStream : public ValueObject {
|
|||
// Reads 'len' bytes from the stream.
|
||||
void ReadBytes(uint8_t* addr, intptr_t len) {
|
||||
ASSERT((end_ - current_) >= len);
|
||||
memmove(addr, current_, len);
|
||||
if (len != 0) {
|
||||
memmove(addr, current_, len);
|
||||
}
|
||||
current_ += len;
|
||||
}
|
||||
|
||||
|
@ -128,23 +130,24 @@ class ReadStream : public ValueObject {
|
|||
|
||||
template <typename T>
|
||||
T Read(uint8_t end_byte_marker) {
|
||||
using Unsigned = typename std::make_unsigned<T>::type;
|
||||
const uint8_t* c = current_;
|
||||
ASSERT(c < end_);
|
||||
uint8_t b = *c++;
|
||||
if (b > kMaxUnsignedDataPerByte) {
|
||||
current_ = c;
|
||||
return static_cast<T>(b) - end_byte_marker;
|
||||
return static_cast<Unsigned>(b) - end_byte_marker;
|
||||
}
|
||||
T r = 0;
|
||||
uint8_t s = 0;
|
||||
do {
|
||||
r |= static_cast<T>(b) << s;
|
||||
r |= static_cast<Unsigned>(b) << s;
|
||||
s += kDataBitsPerByte;
|
||||
ASSERT(c < end_);
|
||||
b = *c++;
|
||||
} while (b <= kMaxUnsignedDataPerByte);
|
||||
current_ = c;
|
||||
return r | ((static_cast<T>(b) - end_byte_marker) << s);
|
||||
return r | ((static_cast<Unsigned>(b) - end_byte_marker) << s);
|
||||
}
|
||||
|
||||
uint16_t Read16(uint8_t end_byte_marker) {
|
||||
|
@ -406,7 +409,9 @@ class WriteStream : public ValueObject {
|
|||
Resize(len);
|
||||
}
|
||||
ASSERT((end_ - current_) >= len);
|
||||
memmove(current_, addr, len);
|
||||
if (len != 0) {
|
||||
memmove(current_, addr, len);
|
||||
}
|
||||
current_ += len;
|
||||
}
|
||||
|
||||
|
@ -550,7 +555,9 @@ class StreamingWriteStream : public ValueObject {
|
|||
|
||||
void WriteBytes(const uint8_t* buffer, intptr_t size) {
|
||||
EnsureAvailable(size);
|
||||
memmove(cursor_, buffer, size);
|
||||
if (size != 0) {
|
||||
memmove(cursor_, buffer, size);
|
||||
}
|
||||
cursor_ += size;
|
||||
}
|
||||
|
||||
|
|
|
@ -181,9 +181,9 @@ class CatchEntryMove {
|
|||
static CatchEntryMove FromSlot(SourceKind kind,
|
||||
intptr_t src_slot,
|
||||
intptr_t dest_slot) {
|
||||
return CatchEntryMove(src_slot,
|
||||
SourceKindField::encode(kind) |
|
||||
(dest_slot << SourceKindField::bitsize()));
|
||||
return CatchEntryMove(src_slot, SourceKindField::encode(kind) |
|
||||
(static_cast<uintptr_t>(dest_slot)
|
||||
<< SourceKindField::bitsize()));
|
||||
}
|
||||
|
||||
static intptr_t EncodePairSource(intptr_t src_lo_slot, intptr_t src_hi_slot) {
|
||||
|
|
|
@ -158,7 +158,7 @@ class Flag {
|
|||
OptionHandler option_handler_;
|
||||
};
|
||||
FlagType type_;
|
||||
bool changed_;
|
||||
bool changed_ = false;
|
||||
};
|
||||
|
||||
Flag* Flags::Lookup(const char* name) {
|
||||
|
|
|
@ -1648,11 +1648,15 @@ void PageSpaceController::EvaluateGarbageCollection(SpaceUsage before,
|
|||
void PageSpaceController::EvaluateAfterLoading(SpaceUsage after) {
|
||||
// Number of pages we can allocate and still be within the desired growth
|
||||
// ratio.
|
||||
intptr_t growth_in_pages =
|
||||
(static_cast<intptr_t>(after.CombinedUsedInWords() /
|
||||
desired_utilization_) -
|
||||
(after.CombinedUsedInWords())) /
|
||||
kPageSizeInWords;
|
||||
intptr_t growth_in_pages;
|
||||
if (desired_utilization_ == 0.0) {
|
||||
growth_in_pages = heap_growth_max_;
|
||||
} else {
|
||||
growth_in_pages = (static_cast<intptr_t>(after.CombinedUsedInWords() /
|
||||
desired_utilization_) -
|
||||
(after.CombinedUsedInWords())) /
|
||||
kPageSizeInWords;
|
||||
}
|
||||
|
||||
// Apply growth cap.
|
||||
growth_in_pages =
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
|
||||
#if defined(TARGET_ARCH_X64)
|
||||
|
||||
#include "platform/unaligned.h"
|
||||
|
||||
#include "vm/code_patcher.h"
|
||||
#include "vm/instructions.h"
|
||||
#include "vm/instructions_x64.h"
|
||||
|
@ -22,7 +24,7 @@ intptr_t IndexFromPPLoadDisp8(uword start) {
|
|||
}
|
||||
|
||||
intptr_t IndexFromPPLoadDisp32(uword start) {
|
||||
int32_t offset = *reinterpret_cast<int32_t*>(start);
|
||||
int32_t offset = LoadUnaligned(reinterpret_cast<int32_t*>(start));
|
||||
return ObjectPool::IndexFromOffset(offset);
|
||||
}
|
||||
|
||||
|
@ -35,7 +37,7 @@ bool DecodeLoadObjectFromPoolOrThread(uword pc, const Code& code, Object* obj) {
|
|||
if ((bytes[0] == 0x49) || (bytes[0] == 0x4d)) {
|
||||
if ((bytes[1] == 0x8b) || (bytes[1] == 0x3b)) { // movq, cmpq
|
||||
if ((bytes[2] & 0xc7) == (0x80 | (THR & 7))) { // [r14+disp32]
|
||||
int32_t offset = *reinterpret_cast<int32_t*>(pc + 3);
|
||||
int32_t offset = LoadUnaligned(reinterpret_cast<int32_t*>(pc + 3));
|
||||
return Thread::ObjectAtOffset(offset, obj);
|
||||
}
|
||||
if ((bytes[2] & 0xc7) == (0x40 | (THR & 7))) { // [r14+disp8]
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#error "Do not include instructions_x64.h directly; use instructions.h instead."
|
||||
#endif
|
||||
|
||||
#include "platform/unaligned.h"
|
||||
#include "vm/allocation.h"
|
||||
|
||||
namespace dart {
|
||||
|
@ -115,13 +116,15 @@ class PcRelativeCallPattern : public InstructionPattern<PcRelativeCallPattern> {
|
|||
explicit PcRelativeCallPattern(uword pc) : InstructionPattern(pc) {}
|
||||
|
||||
int32_t distance() {
|
||||
return *reinterpret_cast<int32_t*>(start() + 1) + kLengthInBytes;
|
||||
return LoadUnaligned(reinterpret_cast<int32_t*>(start() + 1)) +
|
||||
kLengthInBytes;
|
||||
}
|
||||
|
||||
void set_distance(int32_t distance) {
|
||||
// [distance] is relative to the start of the instruction, x64 considers the
|
||||
// offset relative to next PC.
|
||||
*reinterpret_cast<int32_t*>(start() + 1) = distance - kLengthInBytes;
|
||||
StoreUnaligned(reinterpret_cast<int32_t*>(start() + 1),
|
||||
distance - kLengthInBytes);
|
||||
}
|
||||
|
||||
static const int* pattern() {
|
||||
|
@ -162,13 +165,15 @@ class PcRelativeTrampolineJumpPattern : public ValueObject {
|
|||
}
|
||||
|
||||
int32_t distance() {
|
||||
return *reinterpret_cast<int32_t*>(pattern_start_ + 1) + kLengthInBytes;
|
||||
return LoadUnaligned(reinterpret_cast<int32_t*>(pattern_start_ + 1)) +
|
||||
kLengthInBytes;
|
||||
}
|
||||
|
||||
void set_distance(int32_t distance) {
|
||||
// [distance] is relative to the start of the instruction, x64 considers the
|
||||
// offset relative to next PC.
|
||||
*reinterpret_cast<int32_t*>(pattern_start_ + 1) = distance - kLengthInBytes;
|
||||
StoreUnaligned(reinterpret_cast<int32_t*>(pattern_start_ + 1),
|
||||
distance - kLengthInBytes);
|
||||
}
|
||||
|
||||
bool IsValid() const {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#if !defined(DART_PRECOMPILED_RUNTIME)
|
||||
|
||||
#include "platform/unaligned.h"
|
||||
#include "vm/kernel.h"
|
||||
#include "vm/object.h"
|
||||
|
||||
|
@ -236,7 +237,8 @@ class Reader : public ValueObject {
|
|||
ASSERT((size_ >= 4) && (offset >= 0) && (offset <= size_ - 4));
|
||||
uint32_t value;
|
||||
if (raw_buffer_ != NULL) {
|
||||
value = *reinterpret_cast<const uint32_t*>(raw_buffer_ + offset);
|
||||
value = LoadUnaligned(
|
||||
reinterpret_cast<const uint32_t*>(raw_buffer_ + offset));
|
||||
} else {
|
||||
value = typed_data_->GetUint32(offset);
|
||||
}
|
||||
|
@ -259,7 +261,7 @@ class Reader : public ValueObject {
|
|||
|
||||
double ReadDouble() {
|
||||
ASSERT((size_ >= 8) && (offset_ >= 0) && (offset_ <= size_ - 8));
|
||||
double value = ReadUnaligned(
|
||||
double value = LoadUnaligned(
|
||||
reinterpret_cast<const double*>(&this->buffer()[offset_]));
|
||||
offset_ += 8;
|
||||
return value;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#define RUNTIME_VM_MEMORY_REGION_H_
|
||||
|
||||
#include "platform/assert.h"
|
||||
#include "platform/unaligned.h"
|
||||
#include "vm/allocation.h"
|
||||
#include "vm/globals.h"
|
||||
|
||||
|
@ -42,6 +43,11 @@ class MemoryRegion : public ValueObject {
|
|||
*ComputeInternalPointer<T>(offset) = value;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void StoreUnaligned(uword offset, T value) const {
|
||||
dart::StoreUnaligned(ComputeInternalPointer<T>(offset), value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* PointerTo(uword offset) const {
|
||||
return ComputeInternalPointer<T>(offset);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "include/dart_api.h"
|
||||
#include "platform/assert.h"
|
||||
#include "platform/unaligned.h"
|
||||
#include "platform/unicode.h"
|
||||
#include "vm/bit_vector.h"
|
||||
#include "vm/bootstrap.h"
|
||||
|
@ -555,6 +556,7 @@ void Object::InitNullAndBool(Isolate* isolate) {
|
|||
// Allocate a dummy bool object to give true the desired alignment.
|
||||
uword address = heap->Allocate(Bool::InstanceSize(), Heap::kOld);
|
||||
InitializeObject(address, kBoolCid, Bool::InstanceSize());
|
||||
static_cast<BoolPtr>(address + kHeapObjectTag)->ptr()->value_ = false;
|
||||
}
|
||||
{
|
||||
// Allocate true.
|
||||
|
@ -8532,7 +8534,7 @@ InstancePtr Function::ImplicitInstanceClosure(const Instance& receiver) const {
|
|||
intptr_t Function::ComputeClosureHash() const {
|
||||
ASSERT(IsClosureFunction());
|
||||
const Class& cls = Class::Handle(Owner());
|
||||
intptr_t result = String::Handle(name()).Hash();
|
||||
uintptr_t result = String::Handle(name()).Hash();
|
||||
result += String::Handle(Signature()).Hash();
|
||||
result += String::Handle(cls.Name()).Hash();
|
||||
return result;
|
||||
|
@ -15956,18 +15958,19 @@ CodePtr Code::FinalizeCode(FlowGraphCompiler* compiler,
|
|||
|
||||
// Set pointer offsets list in Code object and resolve all handles in
|
||||
// the instruction stream to raw objects.
|
||||
Thread* thread = Thread::Current();
|
||||
for (intptr_t i = 0; i < pointer_offsets.length(); i++) {
|
||||
intptr_t offset_in_instrs = pointer_offsets[i];
|
||||
code.SetPointerOffsetAt(i, offset_in_instrs);
|
||||
uword addr = region.start() + offset_in_instrs;
|
||||
ASSERT(instrs.PayloadStart() <= addr);
|
||||
ASSERT((instrs.PayloadStart() + instrs.Size()) > addr);
|
||||
const Object* object = *reinterpret_cast<Object**>(addr);
|
||||
const Object* object = LoadUnaligned(reinterpret_cast<Object**>(addr));
|
||||
ASSERT(object->IsOld());
|
||||
// N.B. The pointer is embedded in the Instructions object, but visited
|
||||
// through the Code object.
|
||||
code.raw()->ptr()->StorePointer(reinterpret_cast<ObjectPtr*>(addr),
|
||||
object->raw());
|
||||
code.raw()->ptr()->StorePointerUnaligned(
|
||||
reinterpret_cast<ObjectPtr*>(addr), object->raw(), thread);
|
||||
}
|
||||
|
||||
// Write protect instructions and, if supported by OS, use dual mapping
|
||||
|
@ -20476,7 +20479,7 @@ const char* Integer::ToHexCString(Zone* zone) const {
|
|||
ASSERT(IsSmi() || IsMint());
|
||||
int64_t value = AsInt64Value();
|
||||
if (value < 0) {
|
||||
return OS::SCreate(zone, "-0x%" PX64, static_cast<uint64_t>(-value));
|
||||
return OS::SCreate(zone, "-0x%" PX64, -static_cast<uint64_t>(value));
|
||||
} else {
|
||||
return OS::SCreate(zone, "0x%" PX64, static_cast<uint64_t>(value));
|
||||
}
|
||||
|
@ -21116,7 +21119,7 @@ bool String::Equals(const uint16_t* utf16_array, intptr_t len) const {
|
|||
}
|
||||
|
||||
for (intptr_t i = 0; i < len; i++) {
|
||||
if (this->CharAt(i) != utf16_array[i]) {
|
||||
if (this->CharAt(i) != LoadUnaligned(&utf16_array[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -21260,7 +21263,7 @@ StringPtr String::FromUTF16(const uint16_t* utf16_array,
|
|||
Heap::Space space) {
|
||||
bool is_one_byte_string = true;
|
||||
for (intptr_t i = 0; i < array_len; ++i) {
|
||||
if (!Utf::IsLatin1(utf16_array[i])) {
|
||||
if (!Utf::IsLatin1(LoadUnaligned(&utf16_array[i]))) {
|
||||
is_one_byte_string = false;
|
||||
break;
|
||||
}
|
||||
|
@ -21357,7 +21360,7 @@ void String::Copy(const String& dst,
|
|||
if (dst.IsOneByteString()) {
|
||||
NoSafepointScope no_safepoint;
|
||||
for (intptr_t i = 0; i < array_len; ++i) {
|
||||
ASSERT(Utf::IsLatin1(utf16_array[i]));
|
||||
ASSERT(Utf::IsLatin1(LoadUnaligned(&utf16_array[i])));
|
||||
*OneByteString::CharAddr(dst, i + dst_offset) = utf16_array[i];
|
||||
}
|
||||
} else {
|
||||
|
@ -22860,7 +22863,7 @@ Float32x4Ptr Float32x4::New(simd128_value_t value, Heap::Space space) {
|
|||
}
|
||||
|
||||
simd128_value_t Float32x4::value() const {
|
||||
return ReadUnaligned(
|
||||
return LoadUnaligned(
|
||||
reinterpret_cast<const simd128_value_t*>(&raw_ptr()->value_));
|
||||
}
|
||||
|
||||
|
@ -22976,7 +22979,7 @@ int32_t Int32x4::w() const {
|
|||
}
|
||||
|
||||
simd128_value_t Int32x4::value() const {
|
||||
return ReadUnaligned(
|
||||
return LoadUnaligned(
|
||||
reinterpret_cast<const simd128_value_t*>(&raw_ptr()->value_));
|
||||
}
|
||||
|
||||
|
|
|
@ -9796,7 +9796,7 @@ class TypedData : public TypedDataBase {
|
|||
ASSERT((byte_offset >= 0) && \
|
||||
(byte_offset + static_cast<intptr_t>(sizeof(type)) - 1) < \
|
||||
LengthInBytes()); \
|
||||
return ReadUnaligned(ReadOnlyDataAddr<type>(byte_offset)); \
|
||||
return LoadUnaligned(ReadOnlyDataAddr<type>(byte_offset)); \
|
||||
} \
|
||||
void Set##name(intptr_t byte_offset, type value) const { \
|
||||
NoSafepointScope no_safepoint; \
|
||||
|
@ -9931,7 +9931,7 @@ class ExternalTypedData : public TypedDataBase {
|
|||
|
||||
#define TYPED_GETTER_SETTER(name, type) \
|
||||
type Get##name(intptr_t byte_offset) const { \
|
||||
return ReadUnaligned(reinterpret_cast<type*>(DataAddr(byte_offset))); \
|
||||
return LoadUnaligned(reinterpret_cast<type*>(DataAddr(byte_offset))); \
|
||||
} \
|
||||
void Set##name(intptr_t byte_offset, type value) const { \
|
||||
StoreUnaligned(reinterpret_cast<type*>(DataAddr(byte_offset)), value); \
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "vm/object.h"
|
||||
|
||||
#include "platform/unaligned.h"
|
||||
#include "vm/code_patcher.h"
|
||||
#include "vm/hash_table.h"
|
||||
#include "vm/isolate_reload.h"
|
||||
|
@ -74,7 +75,7 @@ void CallSiteResetter::ResetCaches(const Code& code) {
|
|||
for (intptr_t i = 0; i < offsets_length; i++) {
|
||||
int32_t offset = offsets[i];
|
||||
ObjectPtr* object_ptr = reinterpret_cast<ObjectPtr*>(base_address + offset);
|
||||
ObjectPtr raw_object = *object_ptr;
|
||||
ObjectPtr raw_object = LoadUnaligned(object_ptr);
|
||||
if (!raw_object->IsHeapObject()) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -1175,11 +1175,13 @@ void Profiler::DumpStackTrace(uword sp, uword fp, uword pc, bool for_crash) {
|
|||
native_stack_walker.walk();
|
||||
OS::PrintErr("-- End of DumpStackTrace\n");
|
||||
|
||||
if (thread->execution_state() == Thread::kThreadInNative) {
|
||||
TransitionNativeToVM transition(thread);
|
||||
StackFrame::DumpCurrentTrace();
|
||||
} else if (thread->execution_state() == Thread::kThreadInVM) {
|
||||
StackFrame::DumpCurrentTrace();
|
||||
if (thread != nullptr) {
|
||||
if (thread->execution_state() == Thread::kThreadInNative) {
|
||||
TransitionNativeToVM transition(thread);
|
||||
StackFrame::DumpCurrentTrace();
|
||||
} else if (thread->execution_state() == Thread::kThreadInVM) {
|
||||
StackFrame::DumpCurrentTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -537,6 +537,14 @@ class ObjectLayout {
|
|||
}
|
||||
}
|
||||
|
||||
template <typename type>
|
||||
void StorePointerUnaligned(type const* addr, type value, Thread* thread) {
|
||||
StoreUnaligned(const_cast<type*>(addr), value);
|
||||
if (value->IsHeapObject()) {
|
||||
CheckHeapPointerStore(value, thread);
|
||||
}
|
||||
}
|
||||
|
||||
DART_FORCE_INLINE
|
||||
void CheckHeapPointerStore(ObjectPtr value, Thread* thread) {
|
||||
uint32_t source_tags = this->tags_;
|
||||
|
|
|
@ -155,7 +155,7 @@ class Snapshot {
|
|||
|
||||
template <typename T>
|
||||
T Read(intptr_t offset) const {
|
||||
return ReadUnaligned(
|
||||
return LoadUnaligned(
|
||||
reinterpret_cast<const T*>(reinterpret_cast<uword>(this) + offset));
|
||||
}
|
||||
|
||||
|
|
|
@ -114,9 +114,12 @@ IsolateGroup* StackFrame::IsolateGroupOfBareInstructionsFrame() const {
|
|||
}
|
||||
|
||||
isolate_group = this->isolate_group();
|
||||
if (isolate_group->object_store()->code_order_table() != Object::null()) {
|
||||
auto rct = isolate_group->reverse_pc_lookup_cache();
|
||||
if (rct->Contains(pc())) return isolate_group;
|
||||
auto* object_store = isolate_group->object_store();
|
||||
if (object_store != nullptr) {
|
||||
if (object_store->code_order_table() != Object::null()) {
|
||||
auto rct = isolate_group->reverse_pc_lookup_cache();
|
||||
if (rct->Contains(pc())) return isolate_group;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
|
|
@ -553,61 +553,61 @@
|
|||
"builder-tag": "analyzer_use_fasta"
|
||||
}
|
||||
},
|
||||
"dartk-asan-(linux|mac)-(debug|product|release)-(ia32|x64)": {
|
||||
"dartk-asan-(linux|mac)-(debug|product|release)-(ia32|x64|simarm|simarm64)": {
|
||||
"options": {
|
||||
"builder-tag": "asan",
|
||||
"timeout": 240
|
||||
}
|
||||
},
|
||||
"dartk-lsan-(linux|mac)-(debug|product|release)-(ia32|x64)": {
|
||||
"dartk-lsan-(linux|mac)-(debug|product|release)-(ia32|x64|simarm|simarm64)": {
|
||||
"options": {
|
||||
"builder-tag": "lsan",
|
||||
"timeout": 240
|
||||
}
|
||||
},
|
||||
"dartk-msan-linux-(debug|product|release)-x64": {
|
||||
"dartk-msan-linux-(debug|product|release)-(x64|simarm64)": {
|
||||
"options": {
|
||||
"builder-tag": "msan",
|
||||
"timeout": 240
|
||||
}
|
||||
},
|
||||
"dartk-tsan-(linux|mac)-(debug|product|release)-x64": {
|
||||
"dartk-tsan-(linux|mac)-(debug|product|release)-(x64|simarm64)": {
|
||||
"options": {
|
||||
"builder-tag": "tsan",
|
||||
"timeout": 240
|
||||
}
|
||||
},
|
||||
"dartk-ubsan-(linux|mac)-(debug|product|release)-(ia32|x64)": {
|
||||
"dartk-ubsan-(linux|mac)-(debug|product|release)-(ia32|x64|simarm|simarm64)": {
|
||||
"options": {
|
||||
"builder-tag": "ubsan",
|
||||
"timeout": 240
|
||||
}
|
||||
},
|
||||
"dartkp-asan-(linux|mac)-(debug|product|release)-x64": {
|
||||
"dartkp-asan-(linux|mac)-(debug|product|release)-(x64|simarm|simarm64)": {
|
||||
"options": {
|
||||
"builder-tag": "asan",
|
||||
"timeout": 240
|
||||
}
|
||||
},
|
||||
"dartkp-lsan-(linux|mac)-(debug|product|release)-x64": {
|
||||
"dartkp-lsan-(linux|mac)-(debug|product|release)-(x64|simarm|simarm64)": {
|
||||
"options": {
|
||||
"builder-tag": "lsan",
|
||||
"timeout": 240
|
||||
}
|
||||
},
|
||||
"dartkp-msan-linux-(debug|product|release)-x64": {
|
||||
"dartkp-msan-linux-(debug|product|release)-(x64|simarm64)": {
|
||||
"options": {
|
||||
"builder-tag": "msan",
|
||||
"timeout": 240
|
||||
}
|
||||
},
|
||||
"dartkp-tsan-(linux|mac)-(debug|product|release)-x64": {
|
||||
"dartkp-tsan-(linux|mac)-(debug|product|release)-(x64|simarm64)": {
|
||||
"options": {
|
||||
"builder-tag": "tsan",
|
||||
"timeout": 240
|
||||
}
|
||||
},
|
||||
"dartkp-ubsan-(linux|mac)-(debug|product|release)-x64": {
|
||||
"dartkp-ubsan-(linux|mac)-(debug|product|release)-(x64|simarm|simarm64)": {
|
||||
"options": {
|
||||
"builder-tag": "ubsan",
|
||||
"timeout": 240
|
||||
|
@ -3820,7 +3820,7 @@
|
|||
"LSAN_OPTIONS": "check_initialization_order=true:handle_segv=0:detect_leaks=1:detect_stack_use_after_return=0:disable_coredump=0:abort_on_error=1",
|
||||
"MSAN_OPTIONS": "check_initialization_order=true:handle_segv=0:detect_leaks=1:detect_stack_use_after_return=0:disable_coredump=0:abort_on_error=1",
|
||||
"TSAN_OPTIONS": "handle_segv=0:disable_coredump=0:abort_on_error=1",
|
||||
"UBSAN_OPTIONS": "handle_segv=0:disable_coredump=0:abort_on_error=1"
|
||||
"UBSAN_OPTIONS": "handle_segv=0:disable_coredump=0:halt_on_error=1:print_stacktrace=1"
|
||||
},
|
||||
"sanitizer_symbolizer": {
|
||||
"linux": "buildtools/linux-x64/clang/bin/llvm-symbolizer",
|
||||
|
|
|
@ -134,6 +134,12 @@ def UseSysroot(args, gn_args):
|
|||
# Don't use the sysroot if we're given another sysroot.
|
||||
if TargetSysroot(args):
|
||||
return False
|
||||
# Our Debian Jesse sysroot doesn't work with GCC 9
|
||||
if not gn_args['is_clang']:
|
||||
return False
|
||||
# Our Debian Jesse sysroot has incorrect annotations on realloc.
|
||||
if gn_args['is_ubsan']:
|
||||
return False
|
||||
# Otherwise use the sysroot.
|
||||
return True
|
||||
|
||||
|
|
Loading…
Reference in a new issue