[diagnostics] Adapt printing logic for huge TypedArrays

1) don't print off-heap TypedArray elements with --mock-arraybuffer-allocator
2) print integer HeapNumbers in safe integer range with max precision:
   as 9007199254740991.0 instead of 9.0072e+15

Cq-Include-Trybots: luci.v8.try:v8_linux64_ubsan_rel_ng
Bug: v8:4153
Change-Id: Ie79fc08c44374981a840772fde4f414458d31c52
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1883565
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64609}
This commit is contained in:
Igor Sheludko 2019-10-29 12:56:15 +01:00 committed by Commit Bot
parent a6b87fb74e
commit e486763bfd
2 changed files with 29 additions and 3 deletions

View File

@ -365,9 +365,15 @@ void DoPrintElements(std::ostream& os, Object object, int length) { // NOLINT
template <typename ElementType> template <typename ElementType>
void PrintTypedArrayElements(std::ostream& os, const ElementType* data_ptr, void PrintTypedArrayElements(std::ostream& os, const ElementType* data_ptr,
size_t length) { size_t length, bool is_on_heap) {
if (length == 0) return; if (length == 0) return;
size_t previous_index = 0; size_t previous_index = 0;
if (i::FLAG_mock_arraybuffer_allocator && !is_on_heap) {
// Don't try to print data that's not actually allocated.
os << "\n 0-" << length << ": <mocked array buffer bytes>";
return;
}
ElementType previous_value = data_ptr[0]; ElementType previous_value = data_ptr[0];
ElementType value = 0; ElementType value = 0;
for (size_t i = 1; i <= length; i++) { for (size_t i = 1; i <= length; i++) {
@ -491,9 +497,10 @@ void JSObject::PrintElements(std::ostream& os) { // NOLINT
#define PRINT_ELEMENTS(Type, type, TYPE, elementType) \ #define PRINT_ELEMENTS(Type, type, TYPE, elementType) \
case TYPE##_ELEMENTS: { \ case TYPE##_ELEMENTS: { \
size_t length = JSTypedArray::cast(*this).length(); \ size_t length = JSTypedArray::cast(*this).length(); \
bool is_on_heap = JSTypedArray::cast(*this).is_on_heap(); \
const elementType* data_ptr = \ const elementType* data_ptr = \
static_cast<const elementType*>(JSTypedArray::cast(*this).DataPtr()); \ static_cast<const elementType*>(JSTypedArray::cast(*this).DataPtr()); \
PrintTypedArrayElements<elementType>(os, data_ptr, length); \ PrintTypedArrayElements<elementType>(os, data_ptr, length, is_on_heap); \
break; \ break; \
} }
TYPED_ARRAYS(PRINT_ELEMENTS) TYPED_ARRAYS(PRINT_ELEMENTS)
@ -2300,7 +2307,24 @@ void HeapNumber::HeapNumberPrint(std::ostream& os) {
#endif // OBJECT_PRINT #endif // OBJECT_PRINT
void HeapNumber::HeapNumberShortPrint(std::ostream& os) { os << value(); } void HeapNumber::HeapNumberShortPrint(std::ostream& os) {
static constexpr uint64_t kUint64AllBitsSet =
static_cast<uint64_t>(int64_t{-1});
// Min/max integer values representable by 52 bits of mantissa and 1 sign bit.
static constexpr int64_t kMinSafeInteger =
static_cast<int64_t>(kUint64AllBitsSet << 53);
static constexpr int64_t kMaxSafeInteger = -(kMinSafeInteger + 1);
double val = value();
if (val == DoubleToInteger(val) &&
val >= static_cast<double>(kMinSafeInteger) &&
val <= static_cast<double>(kMaxSafeInteger)) {
int64_t i = static_cast<int64_t>(val);
os << i << ".0";
} else {
os << val;
}
}
// TODO(cbruni): remove once the new maptracer is in place. // TODO(cbruni): remove once the new maptracer is in place.
void Name::NameShortPrint() { void Name::NameShortPrint() {

View File

@ -30,6 +30,8 @@ var objects = [
this, this,
true, false, null, undefined, true, false, null, undefined,
1, -1, 1.1, -2.2, -0, 0, 1, -1, 1.1, -2.2, -0, 0,
9007199254740991.0, 9007199254740991.0 + 10,
-9007199254740992.0, -9007199254740992.0 - 10,
Infinity, -Infinity, NaN, Infinity, -Infinity, NaN,
"aasdfasdfasdfasdf", "a"+"b", "aasdfasdfasdfasdf", "a"+"b",
{}, {1:1}, {a:1}, {1:1, 2:2}, Object.create(null), {}, {1:1}, {a:1}, {1:1, 2:2}, Object.create(null),