diff --git a/project/ScalaVersions.scala b/project/ScalaVersions.scala index 77c1567a63..4471b588df 100644 --- a/project/ScalaVersions.scala +++ b/project/ScalaVersions.scala @@ -35,6 +35,8 @@ object ScalaVersions { // Tested in scheduled nightly CI to check compiler plugins // List maintains only upcoming releases, removed from the list after reaching stable status lazy val scala3RCVersions = List( + "3.3.5-RC1", + "3.6.3-RC1", // Hack to make Scala 3.5 the default version until Scala 2.13.16 is relased. (required by scripted tests) // Also 3.6.1 is treated as 3.6.0-RC1 becouse of broken release. Scala 3.6.2 would be the first official release "3.6.1" diff --git a/scalalib/overrides-3.3.0/scala/runtime/LazyVals.scala.patch b/scalalib/overrides-3.3.0/scala/runtime/LazyVals.scala.patch new file mode 100644 index 0000000000..906fbb582c --- /dev/null +++ b/scalalib/overrides-3.3.0/scala/runtime/LazyVals.scala.patch @@ -0,0 +1,171 @@ +--- 3.3.0/scala/runtime/LazyVals.scala ++++ overrides-3.3/scala/runtime/LazyVals.scala +@@ -4,44 +4,13 @@ + + import scala.annotation.* + ++import scala.scalanative.runtime.* ++import scala.scalanative.meta.LinktimeInfo.isMultithreadingEnabled ++ + /** + * Helper methods used in thread-safe lazy vals. + */ + object LazyVals { +- @nowarn +- private[this] val unsafe: sun.misc.Unsafe = { +- def throwInitializationException() = +- throw new ExceptionInInitializerError( +- new IllegalStateException("Can't find instance of sun.misc.Unsafe") +- ) +- try +- val unsafeField = classOf[sun.misc.Unsafe].getDeclaredField("theUnsafe").nn +- if unsafeField.getType == classOf[sun.misc.Unsafe] then +- unsafeField.setAccessible(true) +- unsafeField.get(null).asInstanceOf[sun.misc.Unsafe] +- else +- throwInitializationException() +- catch case _: NoSuchFieldException => +- throwInitializationException() +- } +- +- private[this] val base: Int = { +- val processors = java.lang.Runtime.getRuntime.nn.availableProcessors() +- 8 * processors * processors +- } +- +- private[this] val monitors: Array[Object] = +- Array.tabulate(base)(_ => new Object) +- +- private def getMonitor(obj: Object, fieldId: Int = 0) = { +- var id = (java.lang.System.identityHashCode(obj) + fieldId) % base +- +- if (id < 0) id += base +- monitors(id) +- } +- + private final val LAZY_VAL_MASK = 3L +- private final val debug = false + + /* ------------- Start of public API ------------- */ + +@@ -52,7 +21,10 @@ + * Used to indicate the state of a lazy val that is being + * evaluated and of which other threads await the result. + */ +- final class Waiting extends CountDownLatch(1) with LazyValControlState ++ final class Waiting extends CountDownLatch(1) with LazyValControlState { ++ override def countDown(): Unit = if(isMultithreadingEnabled) super.countDown() ++ override def await(): Unit = if(isMultithreadingEnabled) super.await() ++ } + + /** + * Used to indicate the state of a lazy val that is currently being +@@ -70,94 +42,47 @@ + + def STATE(cur: Long, ord: Int): Long = { + val r = (cur >> (ord * BITS_PER_LAZY_VAL)) & LAZY_VAL_MASK +- if (debug) +- println(s"STATE($cur, $ord) = $r") + r + } + + def CAS(t: Object, offset: Long, e: Long, v: Int, ord: Int): Boolean = { +- if (debug) +- println(s"CAS($t, $offset, $e, $v, $ord)") +- val mask = ~(LAZY_VAL_MASK << ord * BITS_PER_LAZY_VAL) +- val n = (e & mask) | (v.toLong << (ord * BITS_PER_LAZY_VAL)) +- unsafe.compareAndSwapLong(t, offset, e, n) ++ unexpectedUsage() + } + + def objCAS(t: Object, offset: Long, exp: Object, n: Object): Boolean = { +- if (debug) +- println(s"objCAS($t, $exp, $n)") +- unsafe.compareAndSwapObject(t, offset, exp, n) ++ unexpectedUsage() + } + + def setFlag(t: Object, offset: Long, v: Int, ord: Int): Unit = { +- if (debug) +- println(s"setFlag($t, $offset, $v, $ord)") +- var retry = true +- while (retry) { +- val cur = get(t, offset) +- if (STATE(cur, ord) == 1) retry = !CAS(t, offset, cur, v, ord) +- else { +- // cur == 2, somebody is waiting on monitor +- if (CAS(t, offset, cur, v, ord)) { +- val monitor = getMonitor(t, ord) +- monitor.synchronized { +- monitor.notifyAll() +- } +- retry = false +- } +- } +- } ++ unexpectedUsage() + } + + def wait4Notification(t: Object, offset: Long, cur: Long, ord: Int): Unit = { +- if (debug) +- println(s"wait4Notification($t, $offset, $cur, $ord)") +- var retry = true +- while (retry) { +- val cur = get(t, offset) +- val state = STATE(cur, ord) +- if (state == 1) CAS(t, offset, cur, 2, ord) +- else if (state == 2) { +- val monitor = getMonitor(t, ord) +- monitor.synchronized { +- if (STATE(get(t, offset), ord) == 2) // make sure notification did not happen yet. +- monitor.wait() +- } +- } +- else retry = false +- } ++ unexpectedUsage() + } + + def get(t: Object, off: Long): Long = { +- if (debug) +- println(s"get($t, $off)") +- unsafe.getLongVolatile(t, off) ++ unexpectedUsage() + } + + // kept for backward compatibility + def getOffset(clz: Class[_], name: String): Long = { +- @nowarn +- val r = unsafe.objectFieldOffset(clz.getDeclaredField(name)) +- if (debug) +- println(s"getOffset($clz, $name) = $r") +- r ++ unexpectedUsage() + } + + def getStaticFieldOffset(field: java.lang.reflect.Field): Long = { +- @nowarn +- val r = unsafe.staticFieldOffset(field) +- if (debug) +- println(s"getStaticFieldOffset(${field.getDeclaringClass}, ${field.getName}) = $r") +- r ++ unexpectedUsage() + } + + def getOffsetStatic(field: java.lang.reflect.Field) = +- @nowarn +- val r = unsafe.objectFieldOffset(field) +- if (debug) +- println(s"getOffset(${field.getDeclaringClass}, ${field.getName}) = $r") +- r ++ unexpectedUsage() + ++ private def unexpectedUsage() = { ++ throw new IllegalStateException( ++ "Unexpected usage of scala.runtime.LazyVals method, " + ++ "in Scala Native lazy vals use overriden version of this class" ++ ) ++ } + + object Names { + final val state = "STATE" diff --git a/scalalib/overrides-3.3.1/scala/runtime/LazyVals.scala.patch b/scalalib/overrides-3.3.1/scala/runtime/LazyVals.scala.patch new file mode 100644 index 0000000000..906fbb582c --- /dev/null +++ b/scalalib/overrides-3.3.1/scala/runtime/LazyVals.scala.patch @@ -0,0 +1,171 @@ +--- 3.3.0/scala/runtime/LazyVals.scala ++++ overrides-3.3/scala/runtime/LazyVals.scala +@@ -4,44 +4,13 @@ + + import scala.annotation.* + ++import scala.scalanative.runtime.* ++import scala.scalanative.meta.LinktimeInfo.isMultithreadingEnabled ++ + /** + * Helper methods used in thread-safe lazy vals. + */ + object LazyVals { +- @nowarn +- private[this] val unsafe: sun.misc.Unsafe = { +- def throwInitializationException() = +- throw new ExceptionInInitializerError( +- new IllegalStateException("Can't find instance of sun.misc.Unsafe") +- ) +- try +- val unsafeField = classOf[sun.misc.Unsafe].getDeclaredField("theUnsafe").nn +- if unsafeField.getType == classOf[sun.misc.Unsafe] then +- unsafeField.setAccessible(true) +- unsafeField.get(null).asInstanceOf[sun.misc.Unsafe] +- else +- throwInitializationException() +- catch case _: NoSuchFieldException => +- throwInitializationException() +- } +- +- private[this] val base: Int = { +- val processors = java.lang.Runtime.getRuntime.nn.availableProcessors() +- 8 * processors * processors +- } +- +- private[this] val monitors: Array[Object] = +- Array.tabulate(base)(_ => new Object) +- +- private def getMonitor(obj: Object, fieldId: Int = 0) = { +- var id = (java.lang.System.identityHashCode(obj) + fieldId) % base +- +- if (id < 0) id += base +- monitors(id) +- } +- + private final val LAZY_VAL_MASK = 3L +- private final val debug = false + + /* ------------- Start of public API ------------- */ + +@@ -52,7 +21,10 @@ + * Used to indicate the state of a lazy val that is being + * evaluated and of which other threads await the result. + */ +- final class Waiting extends CountDownLatch(1) with LazyValControlState ++ final class Waiting extends CountDownLatch(1) with LazyValControlState { ++ override def countDown(): Unit = if(isMultithreadingEnabled) super.countDown() ++ override def await(): Unit = if(isMultithreadingEnabled) super.await() ++ } + + /** + * Used to indicate the state of a lazy val that is currently being +@@ -70,94 +42,47 @@ + + def STATE(cur: Long, ord: Int): Long = { + val r = (cur >> (ord * BITS_PER_LAZY_VAL)) & LAZY_VAL_MASK +- if (debug) +- println(s"STATE($cur, $ord) = $r") + r + } + + def CAS(t: Object, offset: Long, e: Long, v: Int, ord: Int): Boolean = { +- if (debug) +- println(s"CAS($t, $offset, $e, $v, $ord)") +- val mask = ~(LAZY_VAL_MASK << ord * BITS_PER_LAZY_VAL) +- val n = (e & mask) | (v.toLong << (ord * BITS_PER_LAZY_VAL)) +- unsafe.compareAndSwapLong(t, offset, e, n) ++ unexpectedUsage() + } + + def objCAS(t: Object, offset: Long, exp: Object, n: Object): Boolean = { +- if (debug) +- println(s"objCAS($t, $exp, $n)") +- unsafe.compareAndSwapObject(t, offset, exp, n) ++ unexpectedUsage() + } + + def setFlag(t: Object, offset: Long, v: Int, ord: Int): Unit = { +- if (debug) +- println(s"setFlag($t, $offset, $v, $ord)") +- var retry = true +- while (retry) { +- val cur = get(t, offset) +- if (STATE(cur, ord) == 1) retry = !CAS(t, offset, cur, v, ord) +- else { +- // cur == 2, somebody is waiting on monitor +- if (CAS(t, offset, cur, v, ord)) { +- val monitor = getMonitor(t, ord) +- monitor.synchronized { +- monitor.notifyAll() +- } +- retry = false +- } +- } +- } ++ unexpectedUsage() + } + + def wait4Notification(t: Object, offset: Long, cur: Long, ord: Int): Unit = { +- if (debug) +- println(s"wait4Notification($t, $offset, $cur, $ord)") +- var retry = true +- while (retry) { +- val cur = get(t, offset) +- val state = STATE(cur, ord) +- if (state == 1) CAS(t, offset, cur, 2, ord) +- else if (state == 2) { +- val monitor = getMonitor(t, ord) +- monitor.synchronized { +- if (STATE(get(t, offset), ord) == 2) // make sure notification did not happen yet. +- monitor.wait() +- } +- } +- else retry = false +- } ++ unexpectedUsage() + } + + def get(t: Object, off: Long): Long = { +- if (debug) +- println(s"get($t, $off)") +- unsafe.getLongVolatile(t, off) ++ unexpectedUsage() + } + + // kept for backward compatibility + def getOffset(clz: Class[_], name: String): Long = { +- @nowarn +- val r = unsafe.objectFieldOffset(clz.getDeclaredField(name)) +- if (debug) +- println(s"getOffset($clz, $name) = $r") +- r ++ unexpectedUsage() + } + + def getStaticFieldOffset(field: java.lang.reflect.Field): Long = { +- @nowarn +- val r = unsafe.staticFieldOffset(field) +- if (debug) +- println(s"getStaticFieldOffset(${field.getDeclaringClass}, ${field.getName}) = $r") +- r ++ unexpectedUsage() + } + + def getOffsetStatic(field: java.lang.reflect.Field) = +- @nowarn +- val r = unsafe.objectFieldOffset(field) +- if (debug) +- println(s"getOffset(${field.getDeclaringClass}, ${field.getName}) = $r") +- r ++ unexpectedUsage() + ++ private def unexpectedUsage() = { ++ throw new IllegalStateException( ++ "Unexpected usage of scala.runtime.LazyVals method, " + ++ "in Scala Native lazy vals use overriden version of this class" ++ ) ++ } + + object Names { + final val state = "STATE" diff --git a/scalalib/overrides-3.3.2/scala/runtime/LazyVals.scala.patch b/scalalib/overrides-3.3.2/scala/runtime/LazyVals.scala.patch new file mode 100644 index 0000000000..906fbb582c --- /dev/null +++ b/scalalib/overrides-3.3.2/scala/runtime/LazyVals.scala.patch @@ -0,0 +1,171 @@ +--- 3.3.0/scala/runtime/LazyVals.scala ++++ overrides-3.3/scala/runtime/LazyVals.scala +@@ -4,44 +4,13 @@ + + import scala.annotation.* + ++import scala.scalanative.runtime.* ++import scala.scalanative.meta.LinktimeInfo.isMultithreadingEnabled ++ + /** + * Helper methods used in thread-safe lazy vals. + */ + object LazyVals { +- @nowarn +- private[this] val unsafe: sun.misc.Unsafe = { +- def throwInitializationException() = +- throw new ExceptionInInitializerError( +- new IllegalStateException("Can't find instance of sun.misc.Unsafe") +- ) +- try +- val unsafeField = classOf[sun.misc.Unsafe].getDeclaredField("theUnsafe").nn +- if unsafeField.getType == classOf[sun.misc.Unsafe] then +- unsafeField.setAccessible(true) +- unsafeField.get(null).asInstanceOf[sun.misc.Unsafe] +- else +- throwInitializationException() +- catch case _: NoSuchFieldException => +- throwInitializationException() +- } +- +- private[this] val base: Int = { +- val processors = java.lang.Runtime.getRuntime.nn.availableProcessors() +- 8 * processors * processors +- } +- +- private[this] val monitors: Array[Object] = +- Array.tabulate(base)(_ => new Object) +- +- private def getMonitor(obj: Object, fieldId: Int = 0) = { +- var id = (java.lang.System.identityHashCode(obj) + fieldId) % base +- +- if (id < 0) id += base +- monitors(id) +- } +- + private final val LAZY_VAL_MASK = 3L +- private final val debug = false + + /* ------------- Start of public API ------------- */ + +@@ -52,7 +21,10 @@ + * Used to indicate the state of a lazy val that is being + * evaluated and of which other threads await the result. + */ +- final class Waiting extends CountDownLatch(1) with LazyValControlState ++ final class Waiting extends CountDownLatch(1) with LazyValControlState { ++ override def countDown(): Unit = if(isMultithreadingEnabled) super.countDown() ++ override def await(): Unit = if(isMultithreadingEnabled) super.await() ++ } + + /** + * Used to indicate the state of a lazy val that is currently being +@@ -70,94 +42,47 @@ + + def STATE(cur: Long, ord: Int): Long = { + val r = (cur >> (ord * BITS_PER_LAZY_VAL)) & LAZY_VAL_MASK +- if (debug) +- println(s"STATE($cur, $ord) = $r") + r + } + + def CAS(t: Object, offset: Long, e: Long, v: Int, ord: Int): Boolean = { +- if (debug) +- println(s"CAS($t, $offset, $e, $v, $ord)") +- val mask = ~(LAZY_VAL_MASK << ord * BITS_PER_LAZY_VAL) +- val n = (e & mask) | (v.toLong << (ord * BITS_PER_LAZY_VAL)) +- unsafe.compareAndSwapLong(t, offset, e, n) ++ unexpectedUsage() + } + + def objCAS(t: Object, offset: Long, exp: Object, n: Object): Boolean = { +- if (debug) +- println(s"objCAS($t, $exp, $n)") +- unsafe.compareAndSwapObject(t, offset, exp, n) ++ unexpectedUsage() + } + + def setFlag(t: Object, offset: Long, v: Int, ord: Int): Unit = { +- if (debug) +- println(s"setFlag($t, $offset, $v, $ord)") +- var retry = true +- while (retry) { +- val cur = get(t, offset) +- if (STATE(cur, ord) == 1) retry = !CAS(t, offset, cur, v, ord) +- else { +- // cur == 2, somebody is waiting on monitor +- if (CAS(t, offset, cur, v, ord)) { +- val monitor = getMonitor(t, ord) +- monitor.synchronized { +- monitor.notifyAll() +- } +- retry = false +- } +- } +- } ++ unexpectedUsage() + } + + def wait4Notification(t: Object, offset: Long, cur: Long, ord: Int): Unit = { +- if (debug) +- println(s"wait4Notification($t, $offset, $cur, $ord)") +- var retry = true +- while (retry) { +- val cur = get(t, offset) +- val state = STATE(cur, ord) +- if (state == 1) CAS(t, offset, cur, 2, ord) +- else if (state == 2) { +- val monitor = getMonitor(t, ord) +- monitor.synchronized { +- if (STATE(get(t, offset), ord) == 2) // make sure notification did not happen yet. +- monitor.wait() +- } +- } +- else retry = false +- } ++ unexpectedUsage() + } + + def get(t: Object, off: Long): Long = { +- if (debug) +- println(s"get($t, $off)") +- unsafe.getLongVolatile(t, off) ++ unexpectedUsage() + } + + // kept for backward compatibility + def getOffset(clz: Class[_], name: String): Long = { +- @nowarn +- val r = unsafe.objectFieldOffset(clz.getDeclaredField(name)) +- if (debug) +- println(s"getOffset($clz, $name) = $r") +- r ++ unexpectedUsage() + } + + def getStaticFieldOffset(field: java.lang.reflect.Field): Long = { +- @nowarn +- val r = unsafe.staticFieldOffset(field) +- if (debug) +- println(s"getStaticFieldOffset(${field.getDeclaringClass}, ${field.getName}) = $r") +- r ++ unexpectedUsage() + } + + def getOffsetStatic(field: java.lang.reflect.Field) = +- @nowarn +- val r = unsafe.objectFieldOffset(field) +- if (debug) +- println(s"getOffset(${field.getDeclaringClass}, ${field.getName}) = $r") +- r ++ unexpectedUsage() + ++ private def unexpectedUsage() = { ++ throw new IllegalStateException( ++ "Unexpected usage of scala.runtime.LazyVals method, " + ++ "in Scala Native lazy vals use overriden version of this class" ++ ) ++ } + + object Names { + final val state = "STATE" diff --git a/scalalib/overrides-3.3.3/scala/runtime/LazyVals.scala.patch b/scalalib/overrides-3.3.3/scala/runtime/LazyVals.scala.patch new file mode 100644 index 0000000000..906fbb582c --- /dev/null +++ b/scalalib/overrides-3.3.3/scala/runtime/LazyVals.scala.patch @@ -0,0 +1,171 @@ +--- 3.3.0/scala/runtime/LazyVals.scala ++++ overrides-3.3/scala/runtime/LazyVals.scala +@@ -4,44 +4,13 @@ + + import scala.annotation.* + ++import scala.scalanative.runtime.* ++import scala.scalanative.meta.LinktimeInfo.isMultithreadingEnabled ++ + /** + * Helper methods used in thread-safe lazy vals. + */ + object LazyVals { +- @nowarn +- private[this] val unsafe: sun.misc.Unsafe = { +- def throwInitializationException() = +- throw new ExceptionInInitializerError( +- new IllegalStateException("Can't find instance of sun.misc.Unsafe") +- ) +- try +- val unsafeField = classOf[sun.misc.Unsafe].getDeclaredField("theUnsafe").nn +- if unsafeField.getType == classOf[sun.misc.Unsafe] then +- unsafeField.setAccessible(true) +- unsafeField.get(null).asInstanceOf[sun.misc.Unsafe] +- else +- throwInitializationException() +- catch case _: NoSuchFieldException => +- throwInitializationException() +- } +- +- private[this] val base: Int = { +- val processors = java.lang.Runtime.getRuntime.nn.availableProcessors() +- 8 * processors * processors +- } +- +- private[this] val monitors: Array[Object] = +- Array.tabulate(base)(_ => new Object) +- +- private def getMonitor(obj: Object, fieldId: Int = 0) = { +- var id = (java.lang.System.identityHashCode(obj) + fieldId) % base +- +- if (id < 0) id += base +- monitors(id) +- } +- + private final val LAZY_VAL_MASK = 3L +- private final val debug = false + + /* ------------- Start of public API ------------- */ + +@@ -52,7 +21,10 @@ + * Used to indicate the state of a lazy val that is being + * evaluated and of which other threads await the result. + */ +- final class Waiting extends CountDownLatch(1) with LazyValControlState ++ final class Waiting extends CountDownLatch(1) with LazyValControlState { ++ override def countDown(): Unit = if(isMultithreadingEnabled) super.countDown() ++ override def await(): Unit = if(isMultithreadingEnabled) super.await() ++ } + + /** + * Used to indicate the state of a lazy val that is currently being +@@ -70,94 +42,47 @@ + + def STATE(cur: Long, ord: Int): Long = { + val r = (cur >> (ord * BITS_PER_LAZY_VAL)) & LAZY_VAL_MASK +- if (debug) +- println(s"STATE($cur, $ord) = $r") + r + } + + def CAS(t: Object, offset: Long, e: Long, v: Int, ord: Int): Boolean = { +- if (debug) +- println(s"CAS($t, $offset, $e, $v, $ord)") +- val mask = ~(LAZY_VAL_MASK << ord * BITS_PER_LAZY_VAL) +- val n = (e & mask) | (v.toLong << (ord * BITS_PER_LAZY_VAL)) +- unsafe.compareAndSwapLong(t, offset, e, n) ++ unexpectedUsage() + } + + def objCAS(t: Object, offset: Long, exp: Object, n: Object): Boolean = { +- if (debug) +- println(s"objCAS($t, $exp, $n)") +- unsafe.compareAndSwapObject(t, offset, exp, n) ++ unexpectedUsage() + } + + def setFlag(t: Object, offset: Long, v: Int, ord: Int): Unit = { +- if (debug) +- println(s"setFlag($t, $offset, $v, $ord)") +- var retry = true +- while (retry) { +- val cur = get(t, offset) +- if (STATE(cur, ord) == 1) retry = !CAS(t, offset, cur, v, ord) +- else { +- // cur == 2, somebody is waiting on monitor +- if (CAS(t, offset, cur, v, ord)) { +- val monitor = getMonitor(t, ord) +- monitor.synchronized { +- monitor.notifyAll() +- } +- retry = false +- } +- } +- } ++ unexpectedUsage() + } + + def wait4Notification(t: Object, offset: Long, cur: Long, ord: Int): Unit = { +- if (debug) +- println(s"wait4Notification($t, $offset, $cur, $ord)") +- var retry = true +- while (retry) { +- val cur = get(t, offset) +- val state = STATE(cur, ord) +- if (state == 1) CAS(t, offset, cur, 2, ord) +- else if (state == 2) { +- val monitor = getMonitor(t, ord) +- monitor.synchronized { +- if (STATE(get(t, offset), ord) == 2) // make sure notification did not happen yet. +- monitor.wait() +- } +- } +- else retry = false +- } ++ unexpectedUsage() + } + + def get(t: Object, off: Long): Long = { +- if (debug) +- println(s"get($t, $off)") +- unsafe.getLongVolatile(t, off) ++ unexpectedUsage() + } + + // kept for backward compatibility + def getOffset(clz: Class[_], name: String): Long = { +- @nowarn +- val r = unsafe.objectFieldOffset(clz.getDeclaredField(name)) +- if (debug) +- println(s"getOffset($clz, $name) = $r") +- r ++ unexpectedUsage() + } + + def getStaticFieldOffset(field: java.lang.reflect.Field): Long = { +- @nowarn +- val r = unsafe.staticFieldOffset(field) +- if (debug) +- println(s"getStaticFieldOffset(${field.getDeclaringClass}, ${field.getName}) = $r") +- r ++ unexpectedUsage() + } + + def getOffsetStatic(field: java.lang.reflect.Field) = +- @nowarn +- val r = unsafe.objectFieldOffset(field) +- if (debug) +- println(s"getOffset(${field.getDeclaringClass}, ${field.getName}) = $r") +- r ++ unexpectedUsage() + ++ private def unexpectedUsage() = { ++ throw new IllegalStateException( ++ "Unexpected usage of scala.runtime.LazyVals method, " + ++ "in Scala Native lazy vals use overriden version of this class" ++ ) ++ } + + object Names { + final val state = "STATE" diff --git a/scalalib/overrides-3.3.4/scala/runtime/LazyVals.scala.patch b/scalalib/overrides-3.3.4/scala/runtime/LazyVals.scala.patch new file mode 100644 index 0000000000..906fbb582c --- /dev/null +++ b/scalalib/overrides-3.3.4/scala/runtime/LazyVals.scala.patch @@ -0,0 +1,171 @@ +--- 3.3.0/scala/runtime/LazyVals.scala ++++ overrides-3.3/scala/runtime/LazyVals.scala +@@ -4,44 +4,13 @@ + + import scala.annotation.* + ++import scala.scalanative.runtime.* ++import scala.scalanative.meta.LinktimeInfo.isMultithreadingEnabled ++ + /** + * Helper methods used in thread-safe lazy vals. + */ + object LazyVals { +- @nowarn +- private[this] val unsafe: sun.misc.Unsafe = { +- def throwInitializationException() = +- throw new ExceptionInInitializerError( +- new IllegalStateException("Can't find instance of sun.misc.Unsafe") +- ) +- try +- val unsafeField = classOf[sun.misc.Unsafe].getDeclaredField("theUnsafe").nn +- if unsafeField.getType == classOf[sun.misc.Unsafe] then +- unsafeField.setAccessible(true) +- unsafeField.get(null).asInstanceOf[sun.misc.Unsafe] +- else +- throwInitializationException() +- catch case _: NoSuchFieldException => +- throwInitializationException() +- } +- +- private[this] val base: Int = { +- val processors = java.lang.Runtime.getRuntime.nn.availableProcessors() +- 8 * processors * processors +- } +- +- private[this] val monitors: Array[Object] = +- Array.tabulate(base)(_ => new Object) +- +- private def getMonitor(obj: Object, fieldId: Int = 0) = { +- var id = (java.lang.System.identityHashCode(obj) + fieldId) % base +- +- if (id < 0) id += base +- monitors(id) +- } +- + private final val LAZY_VAL_MASK = 3L +- private final val debug = false + + /* ------------- Start of public API ------------- */ + +@@ -52,7 +21,10 @@ + * Used to indicate the state of a lazy val that is being + * evaluated and of which other threads await the result. + */ +- final class Waiting extends CountDownLatch(1) with LazyValControlState ++ final class Waiting extends CountDownLatch(1) with LazyValControlState { ++ override def countDown(): Unit = if(isMultithreadingEnabled) super.countDown() ++ override def await(): Unit = if(isMultithreadingEnabled) super.await() ++ } + + /** + * Used to indicate the state of a lazy val that is currently being +@@ -70,94 +42,47 @@ + + def STATE(cur: Long, ord: Int): Long = { + val r = (cur >> (ord * BITS_PER_LAZY_VAL)) & LAZY_VAL_MASK +- if (debug) +- println(s"STATE($cur, $ord) = $r") + r + } + + def CAS(t: Object, offset: Long, e: Long, v: Int, ord: Int): Boolean = { +- if (debug) +- println(s"CAS($t, $offset, $e, $v, $ord)") +- val mask = ~(LAZY_VAL_MASK << ord * BITS_PER_LAZY_VAL) +- val n = (e & mask) | (v.toLong << (ord * BITS_PER_LAZY_VAL)) +- unsafe.compareAndSwapLong(t, offset, e, n) ++ unexpectedUsage() + } + + def objCAS(t: Object, offset: Long, exp: Object, n: Object): Boolean = { +- if (debug) +- println(s"objCAS($t, $exp, $n)") +- unsafe.compareAndSwapObject(t, offset, exp, n) ++ unexpectedUsage() + } + + def setFlag(t: Object, offset: Long, v: Int, ord: Int): Unit = { +- if (debug) +- println(s"setFlag($t, $offset, $v, $ord)") +- var retry = true +- while (retry) { +- val cur = get(t, offset) +- if (STATE(cur, ord) == 1) retry = !CAS(t, offset, cur, v, ord) +- else { +- // cur == 2, somebody is waiting on monitor +- if (CAS(t, offset, cur, v, ord)) { +- val monitor = getMonitor(t, ord) +- monitor.synchronized { +- monitor.notifyAll() +- } +- retry = false +- } +- } +- } ++ unexpectedUsage() + } + + def wait4Notification(t: Object, offset: Long, cur: Long, ord: Int): Unit = { +- if (debug) +- println(s"wait4Notification($t, $offset, $cur, $ord)") +- var retry = true +- while (retry) { +- val cur = get(t, offset) +- val state = STATE(cur, ord) +- if (state == 1) CAS(t, offset, cur, 2, ord) +- else if (state == 2) { +- val monitor = getMonitor(t, ord) +- monitor.synchronized { +- if (STATE(get(t, offset), ord) == 2) // make sure notification did not happen yet. +- monitor.wait() +- } +- } +- else retry = false +- } ++ unexpectedUsage() + } + + def get(t: Object, off: Long): Long = { +- if (debug) +- println(s"get($t, $off)") +- unsafe.getLongVolatile(t, off) ++ unexpectedUsage() + } + + // kept for backward compatibility + def getOffset(clz: Class[_], name: String): Long = { +- @nowarn +- val r = unsafe.objectFieldOffset(clz.getDeclaredField(name)) +- if (debug) +- println(s"getOffset($clz, $name) = $r") +- r ++ unexpectedUsage() + } + + def getStaticFieldOffset(field: java.lang.reflect.Field): Long = { +- @nowarn +- val r = unsafe.staticFieldOffset(field) +- if (debug) +- println(s"getStaticFieldOffset(${field.getDeclaringClass}, ${field.getName}) = $r") +- r ++ unexpectedUsage() + } + + def getOffsetStatic(field: java.lang.reflect.Field) = +- @nowarn +- val r = unsafe.objectFieldOffset(field) +- if (debug) +- println(s"getOffset(${field.getDeclaringClass}, ${field.getName}) = $r") +- r ++ unexpectedUsage() + ++ private def unexpectedUsage() = { ++ throw new IllegalStateException( ++ "Unexpected usage of scala.runtime.LazyVals method, " + ++ "in Scala Native lazy vals use overriden version of this class" ++ ) ++ } + + object Names { + final val state = "STATE" diff --git a/scalalib/overrides-3.3/scala/runtime/LazyVals.scala.patch b/scalalib/overrides-3.3/scala/runtime/LazyVals.scala.patch index 906fbb582c..70421b43f4 100644 --- a/scalalib/overrides-3.3/scala/runtime/LazyVals.scala.patch +++ b/scalalib/overrides-3.3/scala/runtime/LazyVals.scala.patch @@ -1,6 +1,6 @@ ---- 3.3.0/scala/runtime/LazyVals.scala +--- 3.3.5-RC1/scala/runtime/LazyVals.scala +++ overrides-3.3/scala/runtime/LazyVals.scala -@@ -4,44 +4,13 @@ +@@ -4,44 +4,14 @@ import scala.annotation.* @@ -13,7 +13,7 @@ object LazyVals { - @nowarn - private[this] val unsafe: sun.misc.Unsafe = { -- def throwInitializationException() = +- def throwInitializationException() = - throw new ExceptionInInitializerError( - new IllegalStateException("Can't find instance of sun.misc.Unsafe") - ) @@ -48,19 +48,16 @@ /* ------------- Start of public API ------------- */ -@@ -52,7 +21,10 @@ - * Used to indicate the state of a lazy val that is being - * evaluated and of which other threads await the result. - */ -- final class Waiting extends CountDownLatch(1) with LazyValControlState -+ final class Waiting extends CountDownLatch(1) with LazyValControlState { +@@ -63,6 +33,8 @@ + * correct. + */ + private def writeReplace(): Any = null + override def countDown(): Unit = if(isMultithreadingEnabled) super.countDown() + override def await(): Unit = if(isMultithreadingEnabled) super.await() -+ } + } /** - * Used to indicate the state of a lazy val that is currently being -@@ -70,94 +42,47 @@ +@@ -86,94 +58,47 @@ def STATE(cur: Long, ord: Int): Long = { val r = (cur >> (ord * BITS_PER_LAZY_VAL)) & LAZY_VAL_MASK @@ -134,12 +131,13 @@ } // kept for backward compatibility - def getOffset(clz: Class[_], name: String): Long = { +- def getOffset(clz: Class[_], name: String): Long = { - @nowarn - val r = unsafe.objectFieldOffset(clz.getDeclaredField(name)) - if (debug) - println(s"getOffset($clz, $name) = $r") - r ++ def getOffset(clz: Class[?], name: String): Long = { + unexpectedUsage() }