diff options
author | Michaël Zasso <targos@protonmail.com> | 2018-03-07 12:37:54 +0100 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2018-03-07 16:48:52 +0100 |
commit | 9759573997a1bbd58fc0ba62e8aa1b4f607ec158 (patch) | |
tree | 616289d04ec752aa94321c52cdfc1a0479631e51 /deps/v8 | |
parent | b4c1222acc6ada19349c4f18723edce105bfce72 (diff) | |
download | node-new-9759573997a1bbd58fc0ba62e8aa1b4f607ec158.tar.gz |
deps: cherry-pick 46c4979 from upstream V8
Original commit message:
Use wider types for max_old_space_size and co.
Make --max_old_space_size and friends work with values >= 2**31.
Such values did not work reliably (or sometimes not all) due to
signed integer overflow in size computations, which is UB.
Fixes https://github.com/nodejs/node/issues/18786.
Bug: chromium:814138
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng
Change-Id: Ibe23cef2417fd5b4a727022b8b0d4b50f1417182
Reviewed-on: https://chromium-review.googlesource.com/927063
Commit-Queue: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51433}
Refs: https://github.com/v8/v8/commit/46c4979e860a9aaf4444616955e896e70e72afbf
PR-URL: https://github.com/nodejs/node/pull/18453
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Yang Guo <yangguo@chromium.org>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Diffstat (limited to 'deps/v8')
-rw-r--r-- | deps/v8/include/v8.h | 22 | ||||
-rw-r--r-- | deps/v8/src/api.cc | 5 | ||||
-rw-r--r-- | deps/v8/src/flag-definitions.h | 18 | ||||
-rw-r--r-- | deps/v8/src/flags.cc | 67 | ||||
-rw-r--r-- | deps/v8/src/heap/heap.cc | 4 | ||||
-rw-r--r-- | deps/v8/src/heap/heap.h | 26 |
6 files changed, 89 insertions, 53 deletions
diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h index acb3efbc71..d5b554dc96 100644 --- a/deps/v8/include/v8.h +++ b/deps/v8/include/v8.h @@ -6030,13 +6030,13 @@ class V8_EXPORT ResourceConstraints { // Returns the max semi-space size in MB. V8_DEPRECATE_SOON("Use max_semi_space_size_in_kb()", - int max_semi_space_size()) { - return static_cast<int>(max_semi_space_size_in_kb_ / 1024); + size_t max_semi_space_size()) { + return max_semi_space_size_in_kb_ / 1024; } // Sets the max semi-space size in MB. V8_DEPRECATE_SOON("Use set_max_semi_space_size_in_kb(size_t limit_in_kb)", - void set_max_semi_space_size(int limit_in_mb)) { + void set_max_semi_space_size(size_t limit_in_mb)) { max_semi_space_size_in_kb_ = limit_in_mb * 1024; } @@ -6050,16 +6050,16 @@ class V8_EXPORT ResourceConstraints { max_semi_space_size_in_kb_ = limit_in_kb; } - int max_old_space_size() const { return max_old_space_size_; } - void set_max_old_space_size(int limit_in_mb) { + size_t max_old_space_size() const { return max_old_space_size_; } + void set_max_old_space_size(size_t limit_in_mb) { max_old_space_size_ = limit_in_mb; } V8_DEPRECATE_SOON("max_executable_size_ is subsumed by max_old_space_size_", - int max_executable_size() const) { + size_t max_executable_size() const) { return max_executable_size_; } V8_DEPRECATE_SOON("max_executable_size_ is subsumed by max_old_space_size_", - void set_max_executable_size(int limit_in_mb)) { + void set_max_executable_size(size_t limit_in_mb)) { max_executable_size_ = limit_in_mb; } uint32_t* stack_limit() const { return stack_limit_; } @@ -6070,17 +6070,15 @@ class V8_EXPORT ResourceConstraints { code_range_size_ = limit_in_mb; } size_t max_zone_pool_size() const { return max_zone_pool_size_; } - void set_max_zone_pool_size(const size_t bytes) { - max_zone_pool_size_ = bytes; - } + void set_max_zone_pool_size(size_t bytes) { max_zone_pool_size_ = bytes; } private: // max_semi_space_size_ is in KB size_t max_semi_space_size_in_kb_; // The remaining limits are in MB - int max_old_space_size_; - int max_executable_size_; + size_t max_old_space_size_; + size_t max_executable_size_; uint32_t* stack_limit_; size_t code_range_size_; size_t max_zone_pool_size_; diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc index 147cc397f2..d258c87853 100644 --- a/deps/v8/src/api.cc +++ b/deps/v8/src/api.cc @@ -979,8 +979,7 @@ void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory, uint64_t virtual_memory_limit) { set_max_semi_space_size_in_kb( i::Heap::ComputeMaxSemiSpaceSize(physical_memory)); - set_max_old_space_size( - static_cast<int>(i::Heap::ComputeMaxOldGenerationSize(physical_memory))); + set_max_old_space_size(i::Heap::ComputeMaxOldGenerationSize(physical_memory)); set_max_zone_pool_size(i::AccountingAllocator::kMaxPoolSize); if (virtual_memory_limit > 0 && i::kRequiresCodeRange) { @@ -995,7 +994,7 @@ void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory, void SetResourceConstraints(i::Isolate* isolate, const ResourceConstraints& constraints) { size_t semi_space_size = constraints.max_semi_space_size_in_kb(); - int old_space_size = constraints.max_old_space_size(); + size_t old_space_size = constraints.max_old_space_size(); size_t code_range_size = constraints.code_range_size(); size_t max_pool_size = constraints.max_zone_pool_size(); if (semi_space_size != 0 || old_space_size != 0 || code_range_size != 0) { diff --git a/deps/v8/src/flag-definitions.h b/deps/v8/src/flag-definitions.h index e40e182dad..8c3a08f81a 100644 --- a/deps/v8/src/flag-definitions.h +++ b/deps/v8/src/flag-definitions.h @@ -161,6 +161,7 @@ struct MaybeBoolFlag { #define DEFINE_INT(nam, def, cmt) FLAG(INT, int, nam, def, cmt) #define DEFINE_UINT(nam, def, cmt) FLAG(UINT, unsigned int, nam, def, cmt) #define DEFINE_FLOAT(nam, def, cmt) FLAG(FLOAT, double, nam, def, cmt) +#define DEFINE_SIZE_T(nam, def, cmt) FLAG(SIZE_T, size_t, nam, def, cmt) #define DEFINE_STRING(nam, def, cmt) FLAG(STRING, const char*, nam, def, cmt) #define DEFINE_ARGS(nam, cmt) \ FLAG(ARGS, JSArguments, nam, {0 COMMA nullptr}, cmt) @@ -168,6 +169,7 @@ struct MaybeBoolFlag { #define DEFINE_ALIAS_BOOL(alias, nam) FLAG_ALIAS(BOOL, bool, alias, nam) #define DEFINE_ALIAS_INT(alias, nam) FLAG_ALIAS(INT, int, alias, nam) #define DEFINE_ALIAS_FLOAT(alias, nam) FLAG_ALIAS(FLOAT, double, alias, nam) +#define DEFINE_ALIAS_SIZE_T(alias, nam) FLAG_ALIAS(SIZE_T, size_t, alias, nam) #define DEFINE_ALIAS_STRING(alias, nam) \ FLAG_ALIAS(STRING, const char*, alias, nam) #define DEFINE_ALIAS_ARGS(alias, nam) FLAG_ALIAS(ARGS, JSArguments, alias, nam) @@ -596,18 +598,18 @@ DEFINE_INT(stress_sampling_allocation_profiler, 0, "Enables sampling allocation profiler with X as a sample interval") // Garbage collections flags. -DEFINE_INT(min_semi_space_size, 0, - "min size of a semi-space (in MBytes), the new space consists of two" - "semi-spaces") -DEFINE_INT(max_semi_space_size, 0, - "max size of a semi-space (in MBytes), the new space consists of two" - "semi-spaces") +DEFINE_SIZE_T(min_semi_space_size, 0, + "min size of a semi-space (in MBytes), the new space consists of " + "two semi-spaces") +DEFINE_SIZE_T(max_semi_space_size, 0, + "max size of a semi-space (in MBytes), the new space consists of " + "two semi-spaces") DEFINE_INT(semi_space_growth_factor, 2, "factor by which to grow the new space") DEFINE_BOOL(experimental_new_space_growth_heuristic, false, "Grow the new space based on the percentage of survivors instead " "of their absolute value.") -DEFINE_INT(max_old_space_size, 0, "max size of the old space (in Mbytes)") -DEFINE_INT(initial_old_space_size, 0, "initial old space size (in Mbytes)") +DEFINE_SIZE_T(max_old_space_size, 0, "max size of the old space (in Mbytes)") +DEFINE_SIZE_T(initial_old_space_size, 0, "initial old space size (in Mbytes)") DEFINE_BOOL(gc_global, false, "always perform global GCs") DEFINE_INT(random_gc_interval, 0, "Collect garbage after random(0, X) allocations. It overrides " diff --git a/deps/v8/src/flags.cc b/deps/v8/src/flags.cc index 693e514e94..2a05ad3da8 100644 --- a/deps/v8/src/flags.cc +++ b/deps/v8/src/flags.cc @@ -5,6 +5,7 @@ #include "src/flags.h" #include <cctype> +#include <cerrno> #include <cstdlib> #include <sstream> @@ -39,6 +40,7 @@ struct Flag { TYPE_INT, TYPE_UINT, TYPE_FLOAT, + TYPE_SIZE_T, TYPE_STRING, TYPE_ARGS }; @@ -81,6 +83,11 @@ struct Flag { return reinterpret_cast<double*>(valptr_); } + size_t* size_t_variable() const { + DCHECK(type_ == TYPE_SIZE_T); + return reinterpret_cast<size_t*>(valptr_); + } + const char* string_value() const { DCHECK(type_ == TYPE_STRING); return *reinterpret_cast<const char**>(valptr_); @@ -119,6 +126,11 @@ struct Flag { return *reinterpret_cast<const double*>(defptr_); } + size_t size_t_default() const { + DCHECK(type_ == TYPE_SIZE_T); + return *reinterpret_cast<const size_t*>(defptr_); + } + const char* string_default() const { DCHECK(type_ == TYPE_STRING); return *reinterpret_cast<const char* const *>(defptr_); @@ -142,6 +154,8 @@ struct Flag { return *uint_variable() == uint_default(); case TYPE_FLOAT: return *float_variable() == float_default(); + case TYPE_SIZE_T: + return *size_t_variable() == size_t_default(); case TYPE_STRING: { const char* str1 = string_value(); const char* str2 = string_default(); @@ -173,6 +187,9 @@ struct Flag { case TYPE_FLOAT: *float_variable() = float_default(); break; + case TYPE_SIZE_T: + *size_t_variable() = size_t_default(); + break; case TYPE_STRING: set_string_value(string_default(), false); break; @@ -201,6 +218,8 @@ static const char* Type2String(Flag::FlagType type) { case Flag::TYPE_UINT: return "uint"; case Flag::TYPE_FLOAT: return "float"; + case Flag::TYPE_SIZE_T: + return "size_t"; case Flag::TYPE_STRING: return "string"; case Flag::TYPE_ARGS: return "arguments"; } @@ -227,6 +246,9 @@ std::ostream& operator<<(std::ostream& os, const Flag& flag) { // NOLINT case Flag::TYPE_FLOAT: os << *flag.float_variable(); break; + case Flag::TYPE_SIZE_T: + os << *flag.size_t_variable(); + break; case Flag::TYPE_STRING: { const char* str = flag.string_value(); os << (str ? str : "nullptr"); @@ -358,6 +380,27 @@ static Flag* FindFlag(const char* name) { return nullptr; } +template <typename T> +bool TryParseUnsigned(Flag* flag, const char* arg, const char* value, + char** endp, T* out_val) { + // We do not use strtoul because it accepts negative numbers. + // Rejects values >= 2**63 when T is 64 bits wide but that + // seems like an acceptable trade-off. + uint64_t max = static_cast<uint64_t>(std::numeric_limits<T>::max()); + errno = 0; + int64_t val = static_cast<int64_t>(strtoll(value, endp, 10)); + if (val < 0 || static_cast<uint64_t>(val) > max || errno != 0) { + PrintF(stderr, + "Error: Value for flag %s of type %s is out of bounds " + "[0-%" PRIu64 + "]\n" + "Try --help for options\n", + arg, Type2String(flag->type()), max); + return false; + } + *out_val = static_cast<T>(val); + return true; +} // static int FlagList::SetFlagsFromCommandLine(int* argc, @@ -422,27 +465,21 @@ int FlagList::SetFlagsFromCommandLine(int* argc, case Flag::TYPE_INT: *flag->int_variable() = static_cast<int>(strtol(value, &endp, 10)); break; - case Flag::TYPE_UINT: { - // We do not use strtoul because it accepts negative numbers. - int64_t val = static_cast<int64_t>(strtoll(value, &endp, 10)); - if (val < 0 || val > std::numeric_limits<unsigned int>::max()) { - PrintF(stderr, - "Error: Value for flag %s of type %s is out of bounds " - "[0-%" PRIu64 - "]\n" - "Try --help for options\n", - arg, Type2String(flag->type()), - static_cast<uint64_t>( - std::numeric_limits<unsigned int>::max())); + case Flag::TYPE_UINT: + if (!TryParseUnsigned(flag, arg, value, &endp, + flag->uint_variable())) { return_code = j; - break; } - *flag->uint_variable() = static_cast<unsigned int>(val); break; - } case Flag::TYPE_FLOAT: *flag->float_variable() = strtod(value, &endp); break; + case Flag::TYPE_SIZE_T: + if (!TryParseUnsigned(flag, arg, value, &endp, + flag->size_t_variable())) { + return_code = j; + } + break; case Flag::TYPE_STRING: flag->set_string_value(value ? StrDup(value) : nullptr, true); break; diff --git a/deps/v8/src/heap/heap.cc b/deps/v8/src/heap/heap.cc index 49c2eccb2d..7f965602b8 100644 --- a/deps/v8/src/heap/heap.cc +++ b/deps/v8/src/heap/heap.cc @@ -5078,8 +5078,8 @@ bool Heap::ConfigureHeap(size_t max_semi_space_size_in_kb, // The new space size must be a power of two to support single-bit testing // for containment. - max_semi_space_size_ = base::bits::RoundUpToPowerOfTwo32( - static_cast<uint32_t>(max_semi_space_size_)); + max_semi_space_size_ = static_cast<size_t>(base::bits::RoundUpToPowerOfTwo64( + static_cast<uint64_t>(max_semi_space_size_))); if (max_semi_space_size_ == kMaxSemiSpaceSizeInKB * KB) { // Start with at least 1*MB semi-space on machines with a lot of memory. diff --git a/deps/v8/src/heap/heap.h b/deps/v8/src/heap/heap.h index 3d8234f392..7cc65479ca 100644 --- a/deps/v8/src/heap/heap.h +++ b/deps/v8/src/heap/heap.h @@ -603,15 +603,15 @@ class Heap { #endif // Semi-space size needs to be a multiple of page size. - static const int kMinSemiSpaceSizeInKB = + static const size_t kMinSemiSpaceSizeInKB = 1 * kPointerMultiplier * ((1 << kPageSizeBits) / KB); - static const int kMaxSemiSpaceSizeInKB = + static const size_t kMaxSemiSpaceSizeInKB = 16 * kPointerMultiplier * ((1 << kPageSizeBits) / KB); // The old space size has to be a multiple of Page::kPageSize. // Sizes are in MB. - static const int kMinOldGenerationSize = 128 * kPointerMultiplier; - static const int kMaxOldGenerationSize = 1024 * kPointerMultiplier; + static const size_t kMinOldGenerationSize = 128 * kPointerMultiplier; + static const size_t kMaxOldGenerationSize = 1024 * kPointerMultiplier; static const int kTraceRingBufferSize = 512; static const int kStacktraceBufferSize = 512; @@ -1360,10 +1360,10 @@ class Heap { size_t MaxOldGenerationSize() { return max_old_generation_size_; } static size_t ComputeMaxOldGenerationSize(uint64_t physical_memory) { - const int old_space_physical_memory_factor = 4; - int computed_size = - static_cast<int>(physical_memory / i::MB / - old_space_physical_memory_factor * kPointerMultiplier); + const size_t old_space_physical_memory_factor = 4; + size_t computed_size = static_cast<size_t>( + physical_memory / i::MB / old_space_physical_memory_factor * + kPointerMultiplier); return Max(Min(computed_size, kMaxOldGenerationSize), kMinOldGenerationSize); } @@ -1375,11 +1375,11 @@ class Heap { uint64_t capped_physical_memory = Max(Min(physical_memory, max_physical_memory), min_physical_memory); // linearly scale max semi-space size: (X-A)/(B-A)*(D-C)+C - int semi_space_size_in_kb = - static_cast<int>(((capped_physical_memory - min_physical_memory) * - (kMaxSemiSpaceSizeInKB - kMinSemiSpaceSizeInKB)) / - (max_physical_memory - min_physical_memory) + - kMinSemiSpaceSizeInKB); + size_t semi_space_size_in_kb = + static_cast<size_t>(((capped_physical_memory - min_physical_memory) * + (kMaxSemiSpaceSizeInKB - kMinSemiSpaceSizeInKB)) / + (max_physical_memory - min_physical_memory) + + kMinSemiSpaceSizeInKB); return RoundUp(semi_space_size_in_kb, (1 << kPageSizeBits) / KB); } |