v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
bigint.h
Go to the documentation of this file.
1// Copyright 2021 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_BIGINT_BIGINT_H_
6#define V8_BIGINT_BIGINT_H_
7
8#include <stdint.h>
9
10#include <algorithm>
11#include <cstring>
12#include <iostream>
13#include <vector>
14
15namespace v8 {
16namespace bigint {
17
18// To play nice with embedders' macros, we define our own DCHECK here.
19// It's only used in this file, and undef'ed at the end.
20#ifdef DEBUG
21#define BIGINT_H_DCHECK(cond) \
22 if (!(cond)) { \
23 std::cerr << __FILE__ << ":" << __LINE__ << ": "; \
24 std::cerr << "Assertion failed: " #cond "\n"; \
25 abort(); \
26 }
27
28extern bool kAdvancedAlgorithmsEnabledInLibrary;
29#else
30#define BIGINT_H_DCHECK(cond) (void(0))
31#endif
32
33// The type of a digit: a register-width unsigned integer.
34using digit_t = uintptr_t;
35using signed_digit_t = intptr_t;
36#if UINTPTR_MAX == 0xFFFFFFFF
37// 32-bit platform.
38using twodigit_t = uint64_t;
39#define HAVE_TWODIGIT_T 1
40static constexpr int kLog2DigitBits = 5;
41#elif UINTPTR_MAX == 0xFFFFFFFFFFFFFFFF
42// 64-bit platform.
43static constexpr int kLog2DigitBits = 6;
44#if defined(__SIZEOF_INT128__)
45using twodigit_t = __uint128_t;
46#define HAVE_TWODIGIT_T 1
47#endif // defined(__SIZEOF_INT128__)
48#else
49#error Unsupported platform.
50#endif
51static constexpr int kDigitBits = 1 << kLog2DigitBits;
52static_assert(kDigitBits == 8 * sizeof(digit_t), "inconsistent type sizes");
53
54// Describes an array of digits, also known as a BigInt. Unsigned.
55// Does not own the memory it points at, and only gives read-only access to it.
56// Digits are stored in little-endian order.
57class Digits {
58 public:
59 // This is the constructor intended for public consumption.
60 Digits(const digit_t* mem, int len)
61 // The const_cast here is ugly, but we need the digits field to be mutable
62 // for the RWDigits subclass. We pinky swear to not mutate the memory with
63 // this class.
64 : Digits(const_cast<digit_t*>(mem), len) {}
65
66 Digits(digit_t* mem, int len) : digits_(mem), len_(len) {
67 // Require 4-byte alignment (even on 64-bit platforms).
68 // TODO(jkummerow): See if we can tighten BigInt alignment in V8 to
69 // system pointer size, and raise this requirement to that.
70 BIGINT_H_DCHECK((reinterpret_cast<uintptr_t>(mem) & 3) == 0);
71 }
72
73 // Provides a "slice" view into another Digits object.
74 Digits(Digits src, int offset, int len)
75 : digits_(src.digits_ + offset),
76 len_(std::max(0, std::min(src.len_ - offset, len))) {
78 }
79
80 Digits() : Digits(static_cast<digit_t*>(nullptr), 0) {}
81
82 // Alternative way to get a "slice" view into another Digits object.
84 BIGINT_H_DCHECK(i >= 0 && i <= len_);
85 return Digits(digits_ + i, len_ - i);
86 }
87
88 // Provides access to individual digits.
90 BIGINT_H_DCHECK(i >= 0 && i < len_);
91 return read_4byte_aligned(i);
92 }
93 // Convenience accessor for the most significant digit.
96 return read_4byte_aligned(len_ - 1);
97 }
98 // Checks "pointer equality" (does not compare digits contents).
99 bool operator==(const Digits& other) const {
100 return digits_ == other.digits_ && len_ == other.len_;
101 }
102
103 // Decrements {len_} until there are no leading zero digits left.
104 void Normalize() {
105 while (len_ > 0 && msd() == 0) len_--;
106 }
107 // Unconditionally drops exactly one leading zero digit.
108 void TrimOne() {
109 BIGINT_H_DCHECK(len_ > 0 && msd() == 0);
110 len_--;
111 }
112
113 int len() { return len_; }
114 const digit_t* digits() const { return digits_; }
115
116 protected:
117 friend class ShiftedDigits;
119 int len_;
120
121 private:
122 // We require externally-provided digits arrays to be 4-byte aligned, but
123 // not necessarily 8-byte aligned; so on 64-bit platforms we use memcpy
124 // to allow unaligned reads.
126 if (sizeof(digit_t) == 4) {
127 return digits_[i];
128 } else {
130 memcpy(&result, static_cast<const void*>(digits_ + i), sizeof(result));
131 return result;
132 }
133 }
134};
135
136// Writable version of a Digits array.
137// Does not own the memory it points at.
138class RWDigits : public Digits {
139 public:
140 RWDigits(digit_t* mem, int len) : Digits(mem, len) {}
141 RWDigits(RWDigits src, int offset, int len) : Digits(src, offset, len) {}
143 BIGINT_H_DCHECK(i >= 0 && i <= len_);
144 return RWDigits(digits_ + i, len_ - i);
145 }
146
147#if UINTPTR_MAX == 0xFFFFFFFF
148 digit_t& operator[](int i) {
149 BIGINT_H_DCHECK(i >= 0 && i < len_);
150 return digits_[i];
151 }
152#else
153 // 64-bit platform. We only require digits arrays to be 4-byte aligned,
154 // so we use a wrapper class to allow regular array syntax while
155 // performing unaligned memory accesses under the hood.
157 public:
158 // Support "X[i] = x" notation.
159 void operator=(digit_t digit) { memcpy(ptr_, &digit, sizeof(digit)); }
160 // Support "X[i] = Y[j]" notation.
162 memcpy(ptr_, src.ptr_, sizeof(digit_t));
163 return *this;
164 }
165 // Support "x = X[i]" notation.
166 operator digit_t() {
168 memcpy(&result, ptr_, sizeof(result));
169 return result;
170 }
171
172 private:
173 // This class is not for public consumption.
174 friend class RWDigits;
175 // Primary constructor.
177 : ptr_(reinterpret_cast<uint32_t*>(ptr)) {}
178 // Required for returning WDR instances from "operator[]" below.
180
181 uint32_t* ptr_;
182 };
183
188#endif
189
190 digit_t* digits() { return digits_; }
191 void set_len(int len) { len_ = len; }
192
193 void Clear() { memset(digits_, 0, len_ * sizeof(digit_t)); }
194};
195
196class Platform {
197 public:
198 virtual ~Platform() = default;
199
200 // If you want the ability to interrupt long-running operations, implement
201 // a Platform subclass that overrides this method. It will be queried
202 // every now and then by long-running operations.
203 virtual bool InterruptRequested() { return false; }
204};
205
206// These are the operations that this library supports.
207// The signatures follow the convention:
208//
209// void Operation(RWDigits results, Digits inputs);
210//
211// You must preallocate the result; use the respective {OperationResultLength}
212// function to determine its minimum required length. The actual result may
213// be smaller, so you should call result.Normalize() on the result.
214//
215// The operations are divided into two groups: "fast" (O(n) with small
216// coefficient) operations are exposed directly as free functions, "slow"
217// operations are methods on a {Processor} object, which provides
218// support for interrupting execution via the {Platform}'s {InterruptRequested}
219// mechanism when it takes too long. These functions return a {Status} value.
220
221// Returns r such that r < 0 if A < B; r > 0 if A > B; r == 0 if A == B.
222// Defined here to be inlineable, which helps ia32 a lot (64-bit platforms
223// don't care).
224inline int Compare(Digits A, Digits B) {
225 A.Normalize();
226 B.Normalize();
227 int diff = A.len() - B.len();
228 if (diff != 0) return diff;
229 int i = A.len() - 1;
230 while (i >= 0 && A[i] == B[i]) i--;
231 if (i < 0) return 0;
232 return A[i] > B[i] ? 1 : -1;
233}
234
235// Z := X + Y
236void Add(RWDigits Z, Digits X, Digits Y);
237// Addition of signed integers. Returns true if the result is negative.
238bool AddSigned(RWDigits Z, Digits X, bool x_negative, Digits Y,
239 bool y_negative);
240// Z := X + 1
241void AddOne(RWDigits Z, Digits X);
242
243// Z := X - Y. Requires X >= Y.
244void Subtract(RWDigits Z, Digits X, Digits Y);
245// Subtraction of signed integers. Returns true if the result is negative.
246bool SubtractSigned(RWDigits Z, Digits X, bool x_negative, Digits Y,
247 bool y_negative);
248// Z := X - 1
249void SubtractOne(RWDigits Z, Digits X);
250
251// The bitwise operations assume that negative BigInts are represented as
252// sign+magnitude. Their behavior depends on the sign of the inputs: negative
253// inputs perform an implicit conversion to two's complement representation.
254// Z := X & Y
255void BitwiseAnd_PosPos(RWDigits Z, Digits X, Digits Y);
256// Call this for a BigInt x = (magnitude=X, negative=true).
257void BitwiseAnd_NegNeg(RWDigits Z, Digits X, Digits Y);
258// Positive X, negative Y. Callers must swap arguments as needed.
259void BitwiseAnd_PosNeg(RWDigits Z, Digits X, Digits Y);
260void BitwiseOr_PosPos(RWDigits Z, Digits X, Digits Y);
261void BitwiseOr_NegNeg(RWDigits Z, Digits X, Digits Y);
262void BitwiseOr_PosNeg(RWDigits Z, Digits X, Digits Y);
263void BitwiseXor_PosPos(RWDigits Z, Digits X, Digits Y);
264void BitwiseXor_NegNeg(RWDigits Z, Digits X, Digits Y);
265void BitwiseXor_PosNeg(RWDigits Z, Digits X, Digits Y);
266void LeftShift(RWDigits Z, Digits X, digit_t shift);
267// RightShiftState is provided by RightShift_ResultLength and used by the actual
268// RightShift to avoid some recomputation.
270 bool must_round_down = false;
271};
272void RightShift(RWDigits Z, Digits X, digit_t shift,
273 const RightShiftState& state);
274
275// Z := (least significant n bits of X, interpreted as a signed n-bit integer).
276// Returns true if the result is negative; Z will hold the absolute value.
277bool AsIntN(RWDigits Z, Digits X, bool x_negative, int n);
278// Z := (least significant n bits of X).
279void AsUintN_Pos(RWDigits Z, Digits X, int n);
280// Same, but X is the absolute value of a negative BigInt.
281void AsUintN_Neg(RWDigits Z, Digits X, int n);
282
283enum class Status { kOk, kInterrupted };
284
285class FromStringAccumulator;
286
288 public:
289 // Takes ownership of {platform}.
290 static Processor* New(Platform* platform);
291
292 // Use this for any std::unique_ptr holding an instance of {Processor}.
293 class Destroyer {
294 public:
295 void operator()(Processor* proc) { proc->Destroy(); }
296 };
297 // When not using std::unique_ptr, call this to delete the instance.
298 void Destroy();
299
300 // Z := X * Y
302 // Q := A / B
304 // R := A % B
306
307 // {out_length} initially contains the allocated capacity of {out}, and
308 // upon return will be set to the actual length of the result string.
309 Status ToString(char* out, uint32_t* out_length, Digits X, int radix,
310 bool sign);
311
312 // Z := the contents of {accumulator}.
313 // Assume that this leaves {accumulator} in unusable state.
315
316 protected:
317 // Use {Destroy} or {Destroyer} instead of the destructor directly.
318 ~Processor() = default;
319};
320
321inline int AddResultLength(int x_length, int y_length) {
322 return std::max(x_length, y_length) + 1;
323}
324inline int AddSignedResultLength(int x_length, int y_length, bool same_sign) {
325 return same_sign ? AddResultLength(x_length, y_length)
326 : std::max(x_length, y_length);
327}
328inline int SubtractResultLength(int x_length, int y_length) { return x_length; }
329inline int SubtractSignedResultLength(int x_length, int y_length,
330 bool same_sign) {
331 return same_sign ? std::max(x_length, y_length)
332 : AddResultLength(x_length, y_length);
333}
335 return X.len() + Y.len();
336}
337constexpr int kBarrettThreshold = 13310;
339#if V8_ADVANCED_BIGINT_ALGORITHMS
340 BIGINT_H_DCHECK(kAdvancedAlgorithmsEnabledInLibrary);
341 // The Barrett division algorithm needs one extra digit for temporary use.
342 int kBarrettExtraScratch = B.len() >= kBarrettThreshold ? 1 : 0;
343#else
344 // If this fails, set -DV8_ADVANCED_BIGINT_ALGORITHMS in any compilation unit
345 // that #includes this header.
346 BIGINT_H_DCHECK(!kAdvancedAlgorithmsEnabledInLibrary);
347 constexpr int kBarrettExtraScratch = 0;
348#endif
349 return A.len() - B.len() + 1 + kBarrettExtraScratch;
350}
351inline int ModuloResultLength(Digits B) { return B.len(); }
352
353uint32_t ToStringResultLength(Digits X, int radix, bool sign);
354// In DEBUG builds, the result of {ToString} will be initialized to this value.
355constexpr char kStringZapValue = '?';
356
357int RightShift_ResultLength(Digits X, bool x_sign, digit_t shift,
358 RightShiftState* state);
359
360// Returns -1 if this "asIntN" operation would be a no-op.
361int AsIntNResultLength(Digits X, bool x_negative, int n);
362// Returns -1 if this "asUintN" operation would be a no-op.
364inline int AsUintN_Neg_ResultLength(int n) {
365 return ((n - 1) / kDigitBits) + 1;
366}
367
368// Support for parsing BigInts from Strings, using an Accumulator object
369// for intermediate state.
370
371class ProcessorImpl;
372
373#if !defined(DEBUG) && (defined(__GNUC__) || defined(__clang__))
374// Clang supports this since 3.9, GCC since 4.x.
375#define ALWAYS_INLINE inline __attribute__((always_inline))
376#elif !defined(DEBUG) && defined(_MSC_VER)
377#define ALWAYS_INLINE __forceinline
378#else
379#define ALWAYS_INLINE inline
380#endif
381
382static constexpr int kStackParts = 8;
383
384// A container object for all metadata required for parsing a BigInt from
385// a string.
386// Aggressively optimized not to waste instructions for small cases, while
387// also scaling transparently to huge cases.
388// Defined here in the header so that it can be inlined.
390 public:
391 enum class Result { kOk, kMaxSizeExceeded };
392
393 // Step 1: Create a FromStringAccumulator instance. For best performance,
394 // stack allocation is recommended.
395 // {max_digits} is only used for refusing to grow beyond a given size
396 // (see "Step 2" below). It does not cause pre-allocation, so feel free to
397 // specify a large maximum.
398 // TODO(jkummerow): The limit applies to the number of intermediate chunks,
399 // whereas the final result will be slightly smaller (depending on {radix}).
400 // So for sufficiently large N, setting max_digits=N here will not actually
401 // allow parsing BigInts with N digits. We can fix that if/when anyone cares.
402 explicit FromStringAccumulator(int max_digits)
403 : max_digits_(std::max(max_digits, kStackParts)) {}
404
405 // Step 2: Call this method to read all characters.
406 // {CharIt} should be a forward iterator and
407 // std::iterator_traits<CharIt>::value_type shall be a character type, such as
408 // uint8_t or uint16_t. {end} should be one past the last character (i.e.
409 // {start == end} would indicate an empty string). Returns the current
410 // position when an invalid character is encountered.
411 template <class CharIt>
412 ALWAYS_INLINE CharIt Parse(CharIt start, CharIt end, digit_t radix);
413
414 // Step 3: Check if a result is available, and determine its required
415 // allocation size (guaranteed to be <= max_digits passed to the constructor).
416 Result result() { return result_; }
418 return std::max(stack_parts_used_, static_cast<int>(heap_parts_.size()));
419 }
420
421 // Step 4: Use BigIntProcessor::FromString() to retrieve the result into an
422 // {RWDigits} struct allocated for the size returned by step 3.
423
424 private:
425 friend class ProcessorImpl;
426
427 template <class CharIt>
428 ALWAYS_INLINE CharIt ParsePowerTwo(CharIt start, CharIt end, digit_t radix);
429
430 ALWAYS_INLINE bool AddPart(digit_t multiplier, digit_t part, bool is_last);
431 ALWAYS_INLINE bool AddPart(digit_t part);
432
434 std::vector<digit_t> heap_parts_;
437 const int max_digits_;
441 uint8_t radix_{0};
442};
443
444// The rest of this file is the inlineable implementation of
445// FromStringAccumulator methods.
446
447#if defined(__GNUC__) || defined(__clang__)
448// Clang supports this since 3.9, GCC since 5.x.
449#define HAVE_BUILTIN_MUL_OVERFLOW 1
450#else
451#define HAVE_BUILTIN_MUL_OVERFLOW 0
452#endif
453
454// Numerical value of the first 127 ASCII characters, using 255 as sentinel
455// for "invalid".
456static constexpr uint8_t kCharValue[] = {
457 255, 255, 255, 255, 255, 255, 255, 255, // 0..7
458 255, 255, 255, 255, 255, 255, 255, 255, // 8..15
459 255, 255, 255, 255, 255, 255, 255, 255, // 16..23
460 255, 255, 255, 255, 255, 255, 255, 255, // 24..31
461 255, 255, 255, 255, 255, 255, 255, 255, // 32..39
462 255, 255, 255, 255, 255, 255, 255, 255, // 40..47
463 0, 1, 2, 3, 4, 5, 6, 7, // 48..55 '0' == 48
464 8, 9, 255, 255, 255, 255, 255, 255, // 56..63 '9' == 57
465 255, 10, 11, 12, 13, 14, 15, 16, // 64..71 'A' == 65
466 17, 18, 19, 20, 21, 22, 23, 24, // 72..79
467 25, 26, 27, 28, 29, 30, 31, 32, // 80..87
468 33, 34, 35, 255, 255, 255, 255, 255, // 88..95 'Z' == 90
469 255, 10, 11, 12, 13, 14, 15, 16, // 96..103 'a' == 97
470 17, 18, 19, 20, 21, 22, 23, 24, // 104..111
471 25, 26, 27, 28, 29, 30, 31, 32, // 112..119
472 33, 34, 35, 255, 255, 255, 255, 255, // 120..127 'z' == 122
473};
474
475// A space- and time-efficient way to map {2,4,8,16,32} to {1,2,3,4,5}.
476static constexpr uint8_t kCharBits[] = {1, 2, 3, 0, 4, 0, 0, 0, 5};
477
478template <class CharIt>
479CharIt FromStringAccumulator::ParsePowerTwo(CharIt current, CharIt end,
480 digit_t radix) {
481 radix_ = static_cast<uint8_t>(radix);
482 const int char_bits = kCharBits[radix >> 2];
483 int bits_left;
484 bool done = false;
485 do {
486 digit_t part = 0;
487 bits_left = kDigitBits;
488 while (true) {
489 digit_t d; // Numeric value of the current character {c}.
490 uint32_t c = *current;
491 if (c > 127 || (d = bigint::kCharValue[c]) >= radix) {
492 done = true;
493 break;
494 }
495
496 if (bits_left < char_bits) break;
497 bits_left -= char_bits;
498 part = (part << char_bits) | d;
499
500 ++current;
501 if (current == end) {
502 done = true;
503 break;
504 }
505 }
506 if (!AddPart(part)) return current;
507 } while (!done);
508 // We use the unused {last_multiplier_} field to
509 // communicate how many bits are unused in the last part.
510 last_multiplier_ = bits_left;
511 return current;
512}
513
514template <class CharIt>
515CharIt FromStringAccumulator::Parse(CharIt start, CharIt end, digit_t radix) {
516 BIGINT_H_DCHECK(2 <= radix && radix <= 36);
517 CharIt current = start;
518#if !HAVE_BUILTIN_MUL_OVERFLOW
519 const digit_t kMaxMultiplier = (~digit_t{0}) / radix;
520#endif
521#if HAVE_TWODIGIT_T // The inlined path requires twodigit_t availability.
522 // The max supported radix is 36, and Math.log2(36) == 5.169..., so we
523 // need at most 5.17 bits per char.
524 static constexpr int kInlineThreshold = kStackParts * kDigitBits * 100 / 517;
526 inline_everything_ = (end - start) <= kInlineThreshold;
527#endif
528 if (!inline_everything_ && (radix & (radix - 1)) == 0) {
529 return ParsePowerTwo(start, end, radix);
530 }
531 bool done = false;
532 do {
533 digit_t multiplier = 1;
534 digit_t part = 0;
535 while (true) {
536 digit_t d; // Numeric value of the current character {c}.
537 uint32_t c = *current;
538 if (c > 127 || (d = bigint::kCharValue[c]) >= radix) {
539 done = true;
540 break;
541 }
542
543#if HAVE_BUILTIN_MUL_OVERFLOW
544 digit_t new_multiplier;
545 if (__builtin_mul_overflow(multiplier, radix, &new_multiplier)) break;
546 multiplier = new_multiplier;
547#else
548 if (multiplier > kMaxMultiplier) break;
549 multiplier *= radix;
550#endif
551 part = part * radix + d;
552
553 ++current;
554 if (current == end) {
555 done = true;
556 break;
557 }
558 }
559 if (!AddPart(multiplier, part, done)) return current;
560 } while (!done);
561 return current;
562}
563
565 bool is_last) {
566#if HAVE_TWODIGIT_T
567 if (inline_everything_) {
568 // Inlined version of {MultiplySingle}.
569 digit_t carry = part;
570 digit_t high = 0;
571 for (int i = 0; i < stack_parts_used_; i++) {
572 twodigit_t result = twodigit_t{stack_parts_[i]} * multiplier;
573 digit_t new_high = result >> bigint::kDigitBits;
574 digit_t low = static_cast<digit_t>(result);
575 result = twodigit_t{low} + high + carry;
576 carry = result >> bigint::kDigitBits;
577 stack_parts_[i] = static_cast<digit_t>(result);
578 high = new_high;
579 }
580 stack_parts_[stack_parts_used_++] = carry + high;
582 return true;
583 }
584#else
586#endif
587 if (is_last) {
588 last_multiplier_ = multiplier;
589 } else {
590 BIGINT_H_DCHECK(max_multiplier_ == 0 || max_multiplier_ == multiplier);
591 max_multiplier_ = multiplier;
592 }
593 return AddPart(part);
594}
595
599 return true;
600 }
601 if (heap_parts_.size() == 0) {
602 // Initialize heap storage. Copy the stack part to make things easier later.
603 heap_parts_.reserve(kStackParts * 2);
604 for (int i = 0; i < kStackParts; i++) {
605 heap_parts_.push_back(stack_parts_[i]);
606 }
607 }
608 if (static_cast<int>(heap_parts_.size()) >= max_digits_) {
610 return false;
611 }
612 heap_parts_.push_back(part);
613 return true;
614}
615
616} // namespace bigint
617} // namespace v8
618
619#undef BIGINT_H_DCHECK
620#undef ALWAYS_INLINE
621#undef HAVE_BUILTIN_MUL_OVERFLOW
622
623#endif // V8_BIGINT_BIGINT_H_
#define ALWAYS_INLINE
Definition bigint.h:379
#define BIGINT_H_DCHECK(cond)
Definition bigint.h:30
digit_t read_4byte_aligned(int i)
Definition bigint.h:125
digit_t * digits_
Definition bigint.h:118
Digits(digit_t *mem, int len)
Definition bigint.h:66
const digit_t * digits() const
Definition bigint.h:114
bool operator==(const Digits &other) const
Definition bigint.h:99
Digits(Digits src, int offset, int len)
Definition bigint.h:74
digit_t operator[](int i)
Definition bigint.h:89
Digits(const digit_t *mem, int len)
Definition bigint.h:60
Digits operator+(int i)
Definition bigint.h:83
digit_t msd()
Definition bigint.h:94
FromStringAccumulator(int max_digits)
Definition bigint.h:402
ALWAYS_INLINE bool AddPart(digit_t multiplier, digit_t part, bool is_last)
Definition bigint.h:564
ALWAYS_INLINE CharIt Parse(CharIt start, CharIt end, digit_t radix)
ALWAYS_INLINE CharIt ParsePowerTwo(CharIt start, CharIt end, digit_t radix)
std::vector< digit_t > heap_parts_
Definition bigint.h:434
digit_t stack_parts_[kStackParts]
Definition bigint.h:433
virtual bool InterruptRequested()
Definition bigint.h:203
virtual ~Platform()=default
void operator()(Processor *proc)
Definition bigint.h:295
Status Modulo(RWDigits R, Digits A, Digits B)
Status Divide(RWDigits Q, Digits A, Digits B)
static Processor * New(Platform *platform)
Status Multiply(RWDigits Z, Digits X, Digits Y)
Status ToString(char *out, uint32_t *out_length, Digits X, int radix, bool sign)
Definition tostring.cc:590
Status FromString(RWDigits Z, FromStringAccumulator *accumulator)
WritableDigitReference(const WritableDigitReference &src)=default
WritableDigitReference & operator=(const WritableDigitReference &src)
Definition bigint.h:161
digit_t * digits()
Definition bigint.h:190
WritableDigitReference operator[](int i)
Definition bigint.h:184
RWDigits operator+(int i)
Definition bigint.h:142
RWDigits(RWDigits src, int offset, int len)
Definition bigint.h:141
void set_len(int len)
Definition bigint.h:191
RWDigits(digit_t *mem, int len)
Definition bigint.h:140
int start
int end
LineAndColumn current
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in allocation gc speed threshold for starting incremental marking via a task in percent of available threshold for starting incremental marking immediately in percent of available Use a single schedule for determining a marking schedule between JS and C objects schedules the minor GC task with kUserVisible priority max worker number of concurrent for NumberOfWorkerThreads start background threads that allocate memory concurrent_array_buffer_sweeping use parallel threads to clear weak refs in the atomic pause trace progress of the incremental marking trace object counts and memory usage report a tick only when allocated zone memory changes by this amount TracingFlags::gc_stats TracingFlags::gc_stats track native contexts that are expected to be garbage collected verify heap pointers before and after GC memory reducer runs GC with ReduceMemoryFootprint flag Maximum number of memory reducer GCs scheduled Old gen GC speed is computed directly from gc tracer counters Perform compaction on full GCs based on V8 s default heuristics Perform compaction on every full GC Perform code space compaction when finalizing a full GC with stack Stress GC compaction to flush out bugs with moving objects flush of baseline code when it has not been executed recently Use time base code flushing instead of age Use a progress bar to scan large objects in increments when incremental marking is active force incremental marking for small heaps and run it more often force marking at random points between and X(inclusive) percent " "of the regular marking start limit") DEFINE_INT(stress_scavenge
int32_t offset
ZoneVector< RpoNumber > & result
STL namespace.
uint32_t ToStringResultLength(Digits X, int radix, bool sign)
Definition tostring.cc:597
int SubtractSignedResultLength(int x_length, int y_length, bool same_sign)
Definition bigint.h:329
void BitwiseXor_NegNeg(RWDigits Z, Digits X, Digits Y)
Definition bitwise.cc:104
bool AsIntN(RWDigits Z, Digits X, bool x_negative, int n)
Definition bitwise.cc:290
void BitwiseAnd_PosPos(RWDigits Z, Digits X, Digits Y)
Definition bitwise.cc:13
intptr_t signed_digit_t
Definition bigint.h:35
void SubtractOne(RWDigits Z, Digits X)
void BitwiseOr_PosNeg(RWDigits Z, Digits X, Digits Y)
Definition bitwise.cc:79
int RightShift_ResultLength(Digits X, bool x_sign, digit_t shift, RightShiftState *state)
Definition bitwise.cc:157
void AddOne(RWDigits Z, Digits X)
void BitwiseXor_PosPos(RWDigits Z, Digits X, Digits Y)
Definition bitwise.cc:91
void LeftShift(RWDigits Z, Digits X, digit_t shift)
Definition bitwise.cc:136
int Compare(Digits A, Digits B)
Definition bigint.h:224
void BitwiseOr_PosPos(RWDigits Z, Digits X, Digits Y)
Definition bitwise.cc:52
static constexpr uint8_t kCharValue[]
Definition bigint.h:456
static constexpr int kDigitBits
Definition bigint.h:51
int ModuloResultLength(Digits B)
Definition bigint.h:351
void BitwiseAnd_NegNeg(RWDigits Z, Digits X, Digits Y)
Definition bitwise.cc:21
constexpr char kStringZapValue
Definition bigint.h:355
int AsIntNResultLength(Digits X, bool x_negative, int n)
Definition bitwise.cc:273
void Add(RWDigits Z, Digits X, Digits Y)
int AddSignedResultLength(int x_length, int y_length, bool same_sign)
Definition bigint.h:324
bool SubtractSigned(RWDigits Z, Digits X, bool x_negative, Digits Y, bool y_negative)
bool AddSigned(RWDigits Z, Digits X, bool x_negative, Digits Y, bool y_negative)
static constexpr int kStackParts
Definition bigint.h:382
void AsUintN_Neg(RWDigits Z, Digits X, int n)
Definition bitwise.cc:341
int SubtractResultLength(int x_length, int y_length)
Definition bigint.h:328
void Subtract(RWDigits Z, Digits X, Digits Y)
static constexpr uint8_t kCharBits[]
Definition bigint.h:476
void BitwiseOr_NegNeg(RWDigits Z, Digits X, Digits Y)
Definition bitwise.cc:62
void RightShift(RWDigits Z, Digits X, digit_t shift, const RightShiftState &state)
Definition bitwise.cc:195
constexpr int kBarrettThreshold
Definition bigint.h:337
int AsUintN_Neg_ResultLength(int n)
Definition bigint.h:364
int DivideResultLength(Digits A, Digits B)
Definition bigint.h:338
int MultiplyResultLength(Digits X, Digits Y)
Definition bigint.h:334
void BitwiseXor_PosNeg(RWDigits Z, Digits X, Digits Y)
Definition bitwise.cc:122
int AddResultLength(int x_length, int y_length)
Definition bigint.h:321
uintptr_t digit_t
Definition bigint.h:34
int AsUintN_Pos_ResultLength(Digits X, int n)
Definition bitwise.cc:325
void BitwiseAnd_PosNeg(RWDigits Z, Digits X, Digits Y)
Definition bitwise.cc:42
void AsUintN_Pos(RWDigits Z, Digits X, int n)
Definition bitwise.cc:336