Commit ee307c74 authored by Jakob Kummerow's avatar Jakob Kummerow Committed by V8 LUCI CQ

[bigint] Move toString conversion to src/bigint/

This just moves the existing algorithm, and translates it from
Handle<BigInt> to Digits as underlying data format.

Bug: v8:11515
Change-Id: Ieefee4e953e14f4c574aebab94d825ddb7c31f8c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2975304
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75391}
parent 3f62253a
...@@ -2433,6 +2433,7 @@ filegroup( ...@@ -2433,6 +2433,7 @@ filegroup(
"src/bigint/div-schoolbook.cc", "src/bigint/div-schoolbook.cc",
"src/bigint/mul-karatsuba.cc", "src/bigint/mul-karatsuba.cc",
"src/bigint/mul-schoolbook.cc", "src/bigint/mul-schoolbook.cc",
"src/bigint/tostring.cc",
"src/bigint/util.h", "src/bigint/util.h",
"src/bigint/vector-arithmetic.cc", "src/bigint/vector-arithmetic.cc",
"src/bigint/vector-arithmetic.h", "src/bigint/vector-arithmetic.h",
......
...@@ -4949,6 +4949,7 @@ v8_source_set("v8_bigint") { ...@@ -4949,6 +4949,7 @@ v8_source_set("v8_bigint") {
"src/bigint/div-schoolbook.cc", "src/bigint/div-schoolbook.cc",
"src/bigint/mul-karatsuba.cc", "src/bigint/mul-karatsuba.cc",
"src/bigint/mul-schoolbook.cc", "src/bigint/mul-schoolbook.cc",
"src/bigint/tostring.cc",
"src/bigint/util.h", "src/bigint/util.h",
"src/bigint/vector-arithmetic.cc", "src/bigint/vector-arithmetic.cc",
"src/bigint/vector-arithmetic.h", "src/bigint/vector-arithmetic.h",
......
...@@ -99,5 +99,12 @@ Status Processor::Modulo(RWDigits R, Digits A, Digits B) { ...@@ -99,5 +99,12 @@ Status Processor::Modulo(RWDigits R, Digits A, Digits B) {
return impl->get_and_clear_status(); return impl->get_and_clear_status();
} }
Status Processor::ToString(char* out, int* out_length, Digits X, int radix,
bool sign) {
ProcessorImpl* impl = static_cast<ProcessorImpl*>(this);
impl->ToString(out, out_length, X, radix, sign);
return impl->get_and_clear_status();
}
} // namespace bigint } // namespace bigint
} // namespace v8 } // namespace v8
...@@ -38,9 +38,12 @@ class ProcessorImpl : public Processor { ...@@ -38,9 +38,12 @@ class ProcessorImpl : public Processor {
void Modulo(RWDigits R, Digits A, Digits B); void Modulo(RWDigits R, Digits A, Digits B);
// {out_length} initially contains the allocated capacity of {out}, and
// upon return will be set to the actual length of the result string.
void ToString(char* out, int* out_length, Digits X, int radix, bool sign);
bool should_terminate() { return status_ == Status::kInterrupted; } bool should_terminate() { return status_ == Status::kInterrupted; }
private:
// Each unit is supposed to represent approximately one CPU {mul} instruction. // Each unit is supposed to represent approximately one CPU {mul} instruction.
// Doesn't need to be accurate; we just want to make sure to check for // Doesn't need to be accurate; we just want to make sure to check for
// interrupt requests every now and then (roughly every 10-100 ms; often // interrupt requests every now and then (roughly every 10-100 ms; often
...@@ -58,6 +61,7 @@ class ProcessorImpl : public Processor { ...@@ -58,6 +61,7 @@ class ProcessorImpl : public Processor {
} }
} }
private:
uintptr_t work_estimate_{0}; uintptr_t work_estimate_{0};
Status status_{Status::kOk}; Status status_{Status::kOk};
Platform* platform_; Platform* platform_;
......
...@@ -240,6 +240,10 @@ class Processor { ...@@ -240,6 +240,10 @@ class Processor {
Status Divide(RWDigits Q, Digits A, Digits B); Status Divide(RWDigits Q, Digits A, Digits B);
// R := A % B // R := A % B
Status Modulo(RWDigits R, Digits A, Digits B); Status Modulo(RWDigits R, Digits A, Digits B);
// {out_length} initially contains the allocated capacity of {out}, and
// upon return will be set to the actual length of the result string.
Status ToString(char* out, int* out_length, Digits X, int radix, bool sign);
}; };
inline int MultiplyResultLength(Digits X, Digits Y) { inline int MultiplyResultLength(Digits X, Digits Y) {
...@@ -250,6 +254,10 @@ inline int DivideResultLength(Digits A, Digits B) { ...@@ -250,6 +254,10 @@ inline int DivideResultLength(Digits A, Digits B) {
} }
inline int ModuloResultLength(Digits B) { return B.len(); } inline int ModuloResultLength(Digits B) { return B.len(); }
int ToStringResultLength(Digits X, int radix, bool sign);
// In DEBUG builds, the result of {ToString} will be initialized to this value.
constexpr char kStringZapValue = '?';
} // namespace bigint } // namespace bigint
} // namespace v8 } // namespace v8
......
This diff is collapsed.
...@@ -50,10 +50,25 @@ constexpr int CountLeadingZeros(uint32_t value) { ...@@ -50,10 +50,25 @@ constexpr int CountLeadingZeros(uint32_t value) {
#endif #endif
} }
inline constexpr int CountTrailingZeros(uint32_t value) {
#if __GNUC__ || __clang__
return value == 0 ? 32 : __builtin_ctz(value);
#elif _MSC_VER
unsigned long index = 0; // NOLINT(runtime/int).
return _BitScanForward(&index, value) ? index : 32;
#else
#error Unsupported compiler.
#endif
}
inline constexpr int BitLength(int n) { inline constexpr int BitLength(int n) {
return 32 - CountLeadingZeros(static_cast<uint32_t>(n)); return 32 - CountLeadingZeros(static_cast<uint32_t>(n));
} }
inline constexpr bool IsPowerOfTwo(int value) {
return value > 0 && (value & (value - 1)) == 0;
}
} // namespace bigint } // namespace bigint
} // namespace v8 } // namespace v8
......
...@@ -56,6 +56,10 @@ inline bool GreaterThanOrEqual(Digits A, Digits B) { ...@@ -56,6 +56,10 @@ inline bool GreaterThanOrEqual(Digits A, Digits B) {
return Compare(A, B) >= 0; return Compare(A, B) >= 0;
} }
inline int BitLength(Digits X) {
return X.len() * kDigitBits - CountLeadingZeros(X.msd());
}
} // namespace bigint } // namespace bigint
} // namespace v8 } // namespace v8
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment