Skip to content

Commit 9759573

Browse files
committed
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 #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: v8/v8@46c4979 PR-URL: #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>
1 parent b4c1222 commit 9759573

File tree

7 files changed

+90
-54
lines changed

7 files changed

+90
-54
lines changed

common.gypi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
# Reset this number to 0 on major V8 upgrades.
2929
# Increment by one for each non-official patch applied to deps/v8.
30-
'v8_embedder_string': '-node.3',
30+
'v8_embedder_string': '-node.4',
3131

3232
# Enable disassembler for `--print-code` v8 options
3333
'v8_enable_disassembler': 1,

deps/v8/include/v8.h

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6030,13 +6030,13 @@ class V8_EXPORT ResourceConstraints {
60306030

60316031
// Returns the max semi-space size in MB.
60326032
V8_DEPRECATE_SOON("Use max_semi_space_size_in_kb()",
6033-
int max_semi_space_size()) {
6034-
return static_cast<int>(max_semi_space_size_in_kb_ / 1024);
6033+
size_t max_semi_space_size()) {
6034+
return max_semi_space_size_in_kb_ / 1024;
60356035
}
60366036

60376037
// Sets the max semi-space size in MB.
60386038
V8_DEPRECATE_SOON("Use set_max_semi_space_size_in_kb(size_t limit_in_kb)",
6039-
void set_max_semi_space_size(int limit_in_mb)) {
6039+
void set_max_semi_space_size(size_t limit_in_mb)) {
60406040
max_semi_space_size_in_kb_ = limit_in_mb * 1024;
60416041
}
60426042

@@ -6050,16 +6050,16 @@ class V8_EXPORT ResourceConstraints {
60506050
max_semi_space_size_in_kb_ = limit_in_kb;
60516051
}
60526052

6053-
int max_old_space_size() const { return max_old_space_size_; }
6054-
void set_max_old_space_size(int limit_in_mb) {
6053+
size_t max_old_space_size() const { return max_old_space_size_; }
6054+
void set_max_old_space_size(size_t limit_in_mb) {
60556055
max_old_space_size_ = limit_in_mb;
60566056
}
60576057
V8_DEPRECATE_SOON("max_executable_size_ is subsumed by max_old_space_size_",
6058-
int max_executable_size() const) {
6058+
size_t max_executable_size() const) {
60596059
return max_executable_size_;
60606060
}
60616061
V8_DEPRECATE_SOON("max_executable_size_ is subsumed by max_old_space_size_",
6062-
void set_max_executable_size(int limit_in_mb)) {
6062+
void set_max_executable_size(size_t limit_in_mb)) {
60636063
max_executable_size_ = limit_in_mb;
60646064
}
60656065
uint32_t* stack_limit() const { return stack_limit_; }
@@ -6070,17 +6070,15 @@ class V8_EXPORT ResourceConstraints {
60706070
code_range_size_ = limit_in_mb;
60716071
}
60726072
size_t max_zone_pool_size() const { return max_zone_pool_size_; }
6073-
void set_max_zone_pool_size(const size_t bytes) {
6074-
max_zone_pool_size_ = bytes;
6075-
}
6073+
void set_max_zone_pool_size(size_t bytes) { max_zone_pool_size_ = bytes; }
60766074

60776075
private:
60786076
// max_semi_space_size_ is in KB
60796077
size_t max_semi_space_size_in_kb_;
60806078

60816079
// The remaining limits are in MB
6082-
int max_old_space_size_;
6083-
int max_executable_size_;
6080+
size_t max_old_space_size_;
6081+
size_t max_executable_size_;
60846082
uint32_t* stack_limit_;
60856083
size_t code_range_size_;
60866084
size_t max_zone_pool_size_;

deps/v8/src/api.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -979,8 +979,7 @@ void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory,
979979
uint64_t virtual_memory_limit) {
980980
set_max_semi_space_size_in_kb(
981981
i::Heap::ComputeMaxSemiSpaceSize(physical_memory));
982-
set_max_old_space_size(
983-
static_cast<int>(i::Heap::ComputeMaxOldGenerationSize(physical_memory)));
982+
set_max_old_space_size(i::Heap::ComputeMaxOldGenerationSize(physical_memory));
984983
set_max_zone_pool_size(i::AccountingAllocator::kMaxPoolSize);
985984

986985
if (virtual_memory_limit > 0 && i::kRequiresCodeRange) {
@@ -995,7 +994,7 @@ void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory,
995994
void SetResourceConstraints(i::Isolate* isolate,
996995
const ResourceConstraints& constraints) {
997996
size_t semi_space_size = constraints.max_semi_space_size_in_kb();
998-
int old_space_size = constraints.max_old_space_size();
997+
size_t old_space_size = constraints.max_old_space_size();
999998
size_t code_range_size = constraints.code_range_size();
1000999
size_t max_pool_size = constraints.max_zone_pool_size();
10011000
if (semi_space_size != 0 || old_space_size != 0 || code_range_size != 0) {

deps/v8/src/flag-definitions.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -161,13 +161,15 @@ struct MaybeBoolFlag {
161161
#define DEFINE_INT(nam, def, cmt) FLAG(INT, int, nam, def, cmt)
162162
#define DEFINE_UINT(nam, def, cmt) FLAG(UINT, unsigned int, nam, def, cmt)
163163
#define DEFINE_FLOAT(nam, def, cmt) FLAG(FLOAT, double, nam, def, cmt)
164+
#define DEFINE_SIZE_T(nam, def, cmt) FLAG(SIZE_T, size_t, nam, def, cmt)
164165
#define DEFINE_STRING(nam, def, cmt) FLAG(STRING, const char*, nam, def, cmt)
165166
#define DEFINE_ARGS(nam, cmt) \
166167
FLAG(ARGS, JSArguments, nam, {0 COMMA nullptr}, cmt)
167168

168169
#define DEFINE_ALIAS_BOOL(alias, nam) FLAG_ALIAS(BOOL, bool, alias, nam)
169170
#define DEFINE_ALIAS_INT(alias, nam) FLAG_ALIAS(INT, int, alias, nam)
170171
#define DEFINE_ALIAS_FLOAT(alias, nam) FLAG_ALIAS(FLOAT, double, alias, nam)
172+
#define DEFINE_ALIAS_SIZE_T(alias, nam) FLAG_ALIAS(SIZE_T, size_t, alias, nam)
171173
#define DEFINE_ALIAS_STRING(alias, nam) \
172174
FLAG_ALIAS(STRING, const char*, alias, nam)
173175
#define DEFINE_ALIAS_ARGS(alias, nam) FLAG_ALIAS(ARGS, JSArguments, alias, nam)
@@ -596,18 +598,18 @@ DEFINE_INT(stress_sampling_allocation_profiler, 0,
596598
"Enables sampling allocation profiler with X as a sample interval")
597599

598600
// Garbage collections flags.
599-
DEFINE_INT(min_semi_space_size, 0,
600-
"min size of a semi-space (in MBytes), the new space consists of two"
601-
"semi-spaces")
602-
DEFINE_INT(max_semi_space_size, 0,
603-
"max size of a semi-space (in MBytes), the new space consists of two"
604-
"semi-spaces")
601+
DEFINE_SIZE_T(min_semi_space_size, 0,
602+
"min size of a semi-space (in MBytes), the new space consists of "
603+
"two semi-spaces")
604+
DEFINE_SIZE_T(max_semi_space_size, 0,
605+
"max size of a semi-space (in MBytes), the new space consists of "
606+
"two semi-spaces")
605607
DEFINE_INT(semi_space_growth_factor, 2, "factor by which to grow the new space")
606608
DEFINE_BOOL(experimental_new_space_growth_heuristic, false,
607609
"Grow the new space based on the percentage of survivors instead "
608610
"of their absolute value.")
609-
DEFINE_INT(max_old_space_size, 0, "max size of the old space (in Mbytes)")
610-
DEFINE_INT(initial_old_space_size, 0, "initial old space size (in Mbytes)")
611+
DEFINE_SIZE_T(max_old_space_size, 0, "max size of the old space (in Mbytes)")
612+
DEFINE_SIZE_T(initial_old_space_size, 0, "initial old space size (in Mbytes)")
611613
DEFINE_BOOL(gc_global, false, "always perform global GCs")
612614
DEFINE_INT(random_gc_interval, 0,
613615
"Collect garbage after random(0, X) allocations. It overrides "

deps/v8/src/flags.cc

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "src/flags.h"
66

77
#include <cctype>
8+
#include <cerrno>
89
#include <cstdlib>
910
#include <sstream>
1011

@@ -39,6 +40,7 @@ struct Flag {
3940
TYPE_INT,
4041
TYPE_UINT,
4142
TYPE_FLOAT,
43+
TYPE_SIZE_T,
4244
TYPE_STRING,
4345
TYPE_ARGS
4446
};
@@ -81,6 +83,11 @@ struct Flag {
8183
return reinterpret_cast<double*>(valptr_);
8284
}
8385

86+
size_t* size_t_variable() const {
87+
DCHECK(type_ == TYPE_SIZE_T);
88+
return reinterpret_cast<size_t*>(valptr_);
89+
}
90+
8491
const char* string_value() const {
8592
DCHECK(type_ == TYPE_STRING);
8693
return *reinterpret_cast<const char**>(valptr_);
@@ -119,6 +126,11 @@ struct Flag {
119126
return *reinterpret_cast<const double*>(defptr_);
120127
}
121128

129+
size_t size_t_default() const {
130+
DCHECK(type_ == TYPE_SIZE_T);
131+
return *reinterpret_cast<const size_t*>(defptr_);
132+
}
133+
122134
const char* string_default() const {
123135
DCHECK(type_ == TYPE_STRING);
124136
return *reinterpret_cast<const char* const *>(defptr_);
@@ -142,6 +154,8 @@ struct Flag {
142154
return *uint_variable() == uint_default();
143155
case TYPE_FLOAT:
144156
return *float_variable() == float_default();
157+
case TYPE_SIZE_T:
158+
return *size_t_variable() == size_t_default();
145159
case TYPE_STRING: {
146160
const char* str1 = string_value();
147161
const char* str2 = string_default();
@@ -173,6 +187,9 @@ struct Flag {
173187
case TYPE_FLOAT:
174188
*float_variable() = float_default();
175189
break;
190+
case TYPE_SIZE_T:
191+
*size_t_variable() = size_t_default();
192+
break;
176193
case TYPE_STRING:
177194
set_string_value(string_default(), false);
178195
break;
@@ -201,6 +218,8 @@ static const char* Type2String(Flag::FlagType type) {
201218
case Flag::TYPE_UINT:
202219
return "uint";
203220
case Flag::TYPE_FLOAT: return "float";
221+
case Flag::TYPE_SIZE_T:
222+
return "size_t";
204223
case Flag::TYPE_STRING: return "string";
205224
case Flag::TYPE_ARGS: return "arguments";
206225
}
@@ -227,6 +246,9 @@ std::ostream& operator<<(std::ostream& os, const Flag& flag) { // NOLINT
227246
case Flag::TYPE_FLOAT:
228247
os << *flag.float_variable();
229248
break;
249+
case Flag::TYPE_SIZE_T:
250+
os << *flag.size_t_variable();
251+
break;
230252
case Flag::TYPE_STRING: {
231253
const char* str = flag.string_value();
232254
os << (str ? str : "nullptr");
@@ -358,6 +380,27 @@ static Flag* FindFlag(const char* name) {
358380
return nullptr;
359381
}
360382

383+
template <typename T>
384+
bool TryParseUnsigned(Flag* flag, const char* arg, const char* value,
385+
char** endp, T* out_val) {
386+
// We do not use strtoul because it accepts negative numbers.
387+
// Rejects values >= 2**63 when T is 64 bits wide but that
388+
// seems like an acceptable trade-off.
389+
uint64_t max = static_cast<uint64_t>(std::numeric_limits<T>::max());
390+
errno = 0;
391+
int64_t val = static_cast<int64_t>(strtoll(value, endp, 10));
392+
if (val < 0 || static_cast<uint64_t>(val) > max || errno != 0) {
393+
PrintF(stderr,
394+
"Error: Value for flag %s of type %s is out of bounds "
395+
"[0-%" PRIu64
396+
"]\n"
397+
"Try --help for options\n",
398+
arg, Type2String(flag->type()), max);
399+
return false;
400+
}
401+
*out_val = static_cast<T>(val);
402+
return true;
403+
}
361404

362405
// static
363406
int FlagList::SetFlagsFromCommandLine(int* argc,
@@ -422,27 +465,21 @@ int FlagList::SetFlagsFromCommandLine(int* argc,
422465
case Flag::TYPE_INT:
423466
*flag->int_variable() = static_cast<int>(strtol(value, &endp, 10));
424467
break;
425-
case Flag::TYPE_UINT: {
426-
// We do not use strtoul because it accepts negative numbers.
427-
int64_t val = static_cast<int64_t>(strtoll(value, &endp, 10));
428-
if (val < 0 || val > std::numeric_limits<unsigned int>::max()) {
429-
PrintF(stderr,
430-
"Error: Value for flag %s of type %s is out of bounds "
431-
"[0-%" PRIu64
432-
"]\n"
433-
"Try --help for options\n",
434-
arg, Type2String(flag->type()),
435-
static_cast<uint64_t>(
436-
std::numeric_limits<unsigned int>::max()));
468+
case Flag::TYPE_UINT:
469+
if (!TryParseUnsigned(flag, arg, value, &endp,
470+
flag->uint_variable())) {
437471
return_code = j;
438-
break;
439472
}
440-
*flag->uint_variable() = static_cast<unsigned int>(val);
441473
break;
442-
}
443474
case Flag::TYPE_FLOAT:
444475
*flag->float_variable() = strtod(value, &endp);
445476
break;
477+
case Flag::TYPE_SIZE_T:
478+
if (!TryParseUnsigned(flag, arg, value, &endp,
479+
flag->size_t_variable())) {
480+
return_code = j;
481+
}
482+
break;
446483
case Flag::TYPE_STRING:
447484
flag->set_string_value(value ? StrDup(value) : nullptr, true);
448485
break;

deps/v8/src/heap/heap.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5078,8 +5078,8 @@ bool Heap::ConfigureHeap(size_t max_semi_space_size_in_kb,
50785078

50795079
// The new space size must be a power of two to support single-bit testing
50805080
// for containment.
5081-
max_semi_space_size_ = base::bits::RoundUpToPowerOfTwo32(
5082-
static_cast<uint32_t>(max_semi_space_size_));
5081+
max_semi_space_size_ = static_cast<size_t>(base::bits::RoundUpToPowerOfTwo64(
5082+
static_cast<uint64_t>(max_semi_space_size_)));
50835083

50845084
if (max_semi_space_size_ == kMaxSemiSpaceSizeInKB * KB) {
50855085
// Start with at least 1*MB semi-space on machines with a lot of memory.

deps/v8/src/heap/heap.h

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -603,15 +603,15 @@ class Heap {
603603
#endif
604604

605605
// Semi-space size needs to be a multiple of page size.
606-
static const int kMinSemiSpaceSizeInKB =
606+
static const size_t kMinSemiSpaceSizeInKB =
607607
1 * kPointerMultiplier * ((1 << kPageSizeBits) / KB);
608-
static const int kMaxSemiSpaceSizeInKB =
608+
static const size_t kMaxSemiSpaceSizeInKB =
609609
16 * kPointerMultiplier * ((1 << kPageSizeBits) / KB);
610610

611611
// The old space size has to be a multiple of Page::kPageSize.
612612
// Sizes are in MB.
613-
static const int kMinOldGenerationSize = 128 * kPointerMultiplier;
614-
static const int kMaxOldGenerationSize = 1024 * kPointerMultiplier;
613+
static const size_t kMinOldGenerationSize = 128 * kPointerMultiplier;
614+
static const size_t kMaxOldGenerationSize = 1024 * kPointerMultiplier;
615615

616616
static const int kTraceRingBufferSize = 512;
617617
static const int kStacktraceBufferSize = 512;
@@ -1360,10 +1360,10 @@ class Heap {
13601360
size_t MaxOldGenerationSize() { return max_old_generation_size_; }
13611361

13621362
static size_t ComputeMaxOldGenerationSize(uint64_t physical_memory) {
1363-
const int old_space_physical_memory_factor = 4;
1364-
int computed_size =
1365-
static_cast<int>(physical_memory / i::MB /
1366-
old_space_physical_memory_factor * kPointerMultiplier);
1363+
const size_t old_space_physical_memory_factor = 4;
1364+
size_t computed_size = static_cast<size_t>(
1365+
physical_memory / i::MB / old_space_physical_memory_factor *
1366+
kPointerMultiplier);
13671367
return Max(Min(computed_size, kMaxOldGenerationSize),
13681368
kMinOldGenerationSize);
13691369
}
@@ -1375,11 +1375,11 @@ class Heap {
13751375
uint64_t capped_physical_memory =
13761376
Max(Min(physical_memory, max_physical_memory), min_physical_memory);
13771377
// linearly scale max semi-space size: (X-A)/(B-A)*(D-C)+C
1378-
int semi_space_size_in_kb =
1379-
static_cast<int>(((capped_physical_memory - min_physical_memory) *
1380-
(kMaxSemiSpaceSizeInKB - kMinSemiSpaceSizeInKB)) /
1381-
(max_physical_memory - min_physical_memory) +
1382-
kMinSemiSpaceSizeInKB);
1378+
size_t semi_space_size_in_kb =
1379+
static_cast<size_t>(((capped_physical_memory - min_physical_memory) *
1380+
(kMaxSemiSpaceSizeInKB - kMinSemiSpaceSizeInKB)) /
1381+
(max_physical_memory - min_physical_memory) +
1382+
kMinSemiSpaceSizeInKB);
13831383
return RoundUp(semi_space_size_in_kb, (1 << kPageSizeBits) / KB);
13841384
}
13851385

0 commit comments

Comments
 (0)