Skip to content

Commit 4044c33

Browse files
committed
Code clean up
1 parent b9ee7d7 commit 4044c33

File tree

2 files changed

+54
-39
lines changed
  • jsoniter-scala-core
    • js/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core
    • jvm-native/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core

2 files changed

+54
-39
lines changed

jsoniter-scala-core/js/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2544,7 +2544,7 @@ final class JsonWriter private[jsoniter_scala](
25442544
else (e2 * 315653) >> 20
25452545
val h = (((e10 + 1) * -217707) >> 16) + e2
25462546
val pow10 = floatPow10s(31 - e10)
2547-
val hi64 = unsignedMultiplyHigh1(pow10, m2.toLong << (h + 37)) // TODO: when dropping JDK 17 support replace by Math.unsignedMultiplyHigh(pow10, m2.toLong << (h + 37))
2547+
val hi64 = unsignedMultiplyHigh(pow10, m2.toLong << (h + 37)) // TODO: when dropping JDK 17 support replace by Math.unsignedMultiplyHigh(pow10, m2.toLong << (h + 37))
25482548
m10 = (hi64 >>> 36).toInt * 10
25492549
val dotOne = hi64 & 0xFFFFFFFFFL
25502550
val halfUlpPlusEven = (pow10 >>> (28 - h)) + ((m2IEEE + 1) & 1)
@@ -2613,10 +2613,6 @@ final class JsonWriter private[jsoniter_scala](
26132613
count = pos
26142614
}
26152615

2616-
@inline
2617-
private[this] def unsignedMultiplyHigh1(x: Long, y: Long): Long =
2618-
Math.multiplyHigh(x, y) + y // Use implementation that works only when x is negative and y is positive
2619-
26202616
// Based on the ingenious work of Xiang JunBo and Wang TieJun
26212617
// "xjb: Fast Float to String Algorithm": https://github.com/xjb714/xjb/blob/4852e533287bd0e8d554c2a9f4cc6eaa93ca799f/fast_f2s.pdf
26222618
// Sources with the license are here: https://github.com/xjb714/xjb
@@ -2656,35 +2652,37 @@ final class JsonWriter private[jsoniter_scala](
26562652
val pow10_1 = pow10s(i)
26572653
val pow10_2 = pow10s(i + 1)
26582654
val cb = m2 << (h + 7)
2659-
val lo64_1 = unsignedMultiplyHigh2(pow10_2, cb) // TODO: when dropping JDK 17 support replace by Math.unsignedMultiplyHigh(pow10_2, cb)
2655+
val lo64_1 = unsignedMultiplyHigh(pow10_2, cb) // TODO: when dropping JDK 17 support replace by Math.unsignedMultiplyHigh(pow10_2, cb)
26602656
val lo64_2 = pow10_1 * cb
2661-
var hi64 = unsignedMultiplyHigh2(pow10_1, cb) // TODO: when dropping JDK 17 support replace by Math.unsignedMultiplyHigh(pow10_1, cb)
2657+
var hi64 = unsignedMultiplyHigh(pow10_1, cb) // TODO: when dropping JDK 17 support replace by Math.unsignedMultiplyHigh(pow10_1, cb)
26622658
val lo64 = lo64_1 + lo64_2
26632659
hi64 += java.lang.Long.compareUnsigned(lo64, lo64_1) >>> 31
26642660
val dotOne = (hi64 << 58) | (lo64 >>> 6)
26652661
val halfUlp = pow10_1 >>> -h
2666-
val even = (m2 + 1L) & 1L
2667-
m10 = hi64 >>> 6
2668-
m10 = (m10 << 3) + (m10 << 1)
2669-
if (java.lang.Long.compareUnsigned(halfUlp + even, -1 - dotOne) > 0) m10 += 10L
2670-
else if (m2IEEE != 0) {
2671-
if (java.lang.Long.compareUnsigned(halfUlp + even, dotOne) <= 0) {
2672-
m10 = (unsignedMultiplyHigh2(lo64, 10L) + (hi64 << 3) + (hi64 << 1) + { // TODO: when dropping JDK 17 support replace by Math.unsignedMultiplyHigh(lo64, 10L)
2673-
if (dotOne == 0x4000000000000000L) 0x1FL
2674-
else 0x20L
2675-
}) >>> 6
2662+
val even = (m2.toInt + 1) & 1
2663+
if (java.lang.Long.compareUnsigned(halfUlp + even, -1 - dotOne) > 0) {
2664+
m10 = hi64 >>> 6
2665+
m10 = (m10 << 3) + (m10 << 1) + 10L
2666+
} else if (m2IEEE != 0) {
2667+
if (java.lang.Long.compareUnsigned(halfUlp + even, dotOne) > 0) {
2668+
m10 = hi64 >>> 6
2669+
m10 = (m10 << 3) + (m10 << 1)
2670+
} else {
2671+
m10 = calculateM10(hi64, lo64, dotOne)
26762672
}
26772673
} else {
26782674
var tmp1 = dotOne >>> 4
26792675
tmp1 = (tmp1 << 3) + (tmp1 << 1)
26802676
var tmp2 = halfUlp >>> 4
26812677
tmp2 += tmp2 << 2
2682-
if (java.lang.Long.compareUnsigned((tmp1 << 4) >>> 4, tmp2) > 0) m10 += (tmp1 >>> 60).toInt + 1
2683-
else if (java.lang.Long.compareUnsigned(halfUlp >>> 1, dotOne) <= 0) {
2684-
m10 = (unsignedMultiplyHigh2(lo64, 10L) + (hi64 << 3) + (hi64 << 1) + { // TODO: when dropping JDK 17 support replace by Math.unsignedMultiplyHigh(lo64, 10L)
2685-
if (dotOne == 0x4000000000000000L) 0x1FL
2686-
else 0x20L
2687-
}) >>> 6
2678+
if (java.lang.Long.compareUnsigned((tmp1 << 4) >>> 4, tmp2) > 0) {
2679+
m10 = hi64 >>> 6
2680+
m10 = (m10 << 3) + (m10 << 1) + ((tmp1 >>> 60).toInt + 1)
2681+
} else if (java.lang.Long.compareUnsigned(halfUlp >>> 1, dotOne) > 0) {
2682+
m10 = hi64 >>> 6
2683+
m10 = (m10 << 3) + (m10 << 1)
2684+
} else {
2685+
m10 = calculateM10(hi64, lo64, dotOne)
26882686
}
26892687
}
26902688
}
@@ -2743,9 +2741,25 @@ final class JsonWriter private[jsoniter_scala](
27432741
count = pos
27442742
}
27452743

2744+
// 64-bit unsigned multiplication was adopted from the great Hacker's Delight function
2745+
// (Henry S. Warren, Hacker's Delight, Addison-Wesley, 2nd edition, Fig. 8.2)
2746+
// https://doc.lagout.org/security/Hackers%20Delight.pdf
2747+
@inline
2748+
private[this] def unsignedMultiplyHigh(x: Long, y: Long): Long = {
2749+
val xl = x & 0xFFFFFFFFL
2750+
val xh = x >>> 32
2751+
val yl = y & 0xFFFFFFFFL
2752+
val yh = y >>> 32
2753+
val t = xh * yl + (xl * yl >>> 32)
2754+
xh * yh + (t >>> 32) + (xl * yh + (t & 0xFFFFFFFFL) >>> 32)
2755+
}
2756+
27462757
@inline
2747-
private[this] def unsignedMultiplyHigh2(x: Long, y: Long): Long =
2748-
Math.multiplyHigh(x, y) + (y & (x >> 63)) // Use implementation that works only when y is positive
2758+
private[this] def calculateM10(hi: Long, lo: Long, dotOne: Long): Long = ((hi << 3) + (hi << 1) +
2759+
((lo >>> 61).toInt + (lo >>> 63).toInt + (java.lang.Long.compareUnsigned((lo << 3) + (lo << 1), lo << 1) >>> 31) + {
2760+
if (dotOne == 0x4000000000000000L) 0x1F
2761+
else 0x20
2762+
})) >>> 6
27492763

27502764
@inline
27512765
private[this] def digitCount(x: Long): Int =

jsoniter-scala-core/jvm-native/src/main/scala/com/github/plokhotnyuk/jsoniter_scala/core/JsonWriter.scala

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2377,25 +2377,26 @@ final class JsonWriter private[jsoniter_scala](
23772377
hi64 += java.lang.Long.compareUnsigned(lo64, lo64_1) >>> 31
23782378
val dotOne = (hi64 << 58) | (lo64 >>> 6)
23792379
val halfUlp = pow10_1 >>> -h
2380-
val even = (m2 + 1L) & 1L
2381-
m10 = hi64 >>> 6
2382-
m10 = (m10 << 3) + (m10 << 1)
2383-
if (java.lang.Long.compareUnsigned(halfUlp + even, -1 - dotOne) > 0) m10 += 10L
2384-
else if (m2IEEE != 0) {
2385-
if (java.lang.Long.compareUnsigned(halfUlp + even, dotOne) <= 0) {
2386-
m10 = (unsignedMultiplyHigh2(lo64, 10L) + (hi64 << 3) + (hi64 << 1) + { // TODO: when dropping JDK 17 support replace by Math.unsignedMultiplyHigh(lo64, 10L)
2380+
val even = (m2.toInt + 1) & 1
2381+
if (java.lang.Long.compareUnsigned(halfUlp + even, -1 - dotOne) > 0) {
2382+
m10 = (hi64 >>> 6) * 10L + 10L
2383+
} else if (m2IEEE != 0) {
2384+
if (java.lang.Long.compareUnsigned(halfUlp + even, dotOne) > 0) {
2385+
m10 = (hi64 >>> 6) * 10L
2386+
} else {
2387+
m10 = (hi64 * 10L + unsignedMultiplyHigh2(lo64, 10L) + { // TODO: when dropping JDK 17 support replace by Math.unsignedMultiplyHigh(lo64, 10L)
23872388
if (dotOne == 0x4000000000000000L) 0x1FL
23882389
else 0x20L
23892390
}) >>> 6
23902391
}
23912392
} else {
2392-
var tmp1 = dotOne >>> 4
2393-
tmp1 = (tmp1 << 3) + (tmp1 << 1)
2394-
var tmp2 = halfUlp >>> 4
2395-
tmp2 += tmp2 << 2
2396-
if (java.lang.Long.compareUnsigned((tmp1 << 4) >>> 4, tmp2) > 0) m10 += (tmp1 >>> 60).toInt + 1
2397-
else if (java.lang.Long.compareUnsigned(halfUlp >>> 1, dotOne) <= 0) {
2398-
m10 = (unsignedMultiplyHigh2(lo64, 10L) + (hi64 << 3) + (hi64 << 1) + { // TODO: when dropping JDK 17 support replace by Math.unsignedMultiplyHigh(lo64, 10L)
2393+
val tmp = (dotOne >>> 4) * 10L
2394+
if (java.lang.Long.compareUnsigned((tmp << 4) >>> 4, (halfUlp >>> 4) * 5L) > 0) {
2395+
m10 = (hi64 >>> 6) * 10L + ((tmp >>> 60).toInt + 1)
2396+
} else if (java.lang.Long.compareUnsigned(halfUlp >>> 1, dotOne) > 0) {
2397+
m10 = (hi64 >>> 6) * 10L
2398+
} else {
2399+
m10 = (hi64 * 10L + unsignedMultiplyHigh2(lo64, 10L) + { // TODO: when dropping JDK 17 support replace by Math.unsignedMultiplyHigh(lo64, 10L)
23992400
if (dotOne == 0x4000000000000000L) 0x1FL
24002401
else 0x20L
24012402
}) >>> 6

0 commit comments

Comments
 (0)