--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-interna...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
1) Looks like subsametypeRecusions and pendingSubTypes guard against
infinite recusion during subtyping. There's quite a number of
recursive calls in isSubType, so I can't immediately see what cases
could lead to stack overflows when unguarded. Could you please show an
example?
4) But we have this nasty skolemizationLevel, which seems necessary
for type var inference. From the code I can see that it's incremented
every time subtyping checks recur into existentials, but I can't
exactly figure out an example. Could you please provide one?
5) Any other comments? Maybe there's some sort of a doc for the type
var business? At a glance it looks quite opaque. Suspended type vars,
untouchables, etc - a lot to absorb.
I agree mutation should be avoided.However, retro-fitting context-tracking (the only alternative I cant think of) into methods like isSubtype (and all its callers) is no easy feat.
I agree mutation should be avoided.However, retro-fitting context-tracking (the only alternative I cant think of) into methods like isSubtype (and all its callers) is no easy feat.
you could just use Java's ConcurrentHashMap or Cliff Click's NonBlockingHashMap, which IIRC uses advanced forms of the scheme Rex Kerr described.
On Sun, 3 Feb 2013 23:03:30 -0800 (PST)
> Il giorno lunedì 4 febbraio 2013 03:28:10 UTC+1, Adriaan Moors ha scritto:To avoid classloader leaks, don't set an initial value on ThreadLocals
>
> > I agree mutation should be avoided.
> > However, retro-fitting context-tracking (the only alternative I cant think
> > of) into methods like isSubtype (and all its callers) is no easy feat.
> >
>
> You mean threading an extra parameter through all callers?
>
> Then what about thread-locals, at least as a short/medium-term solution?
> From the description, skolemizationLevel, subsametypeRecusions and
> pendingSubTypes are completely independent among threads (since they guard
> against infinite recursion), so thread-locals seem quite appropriate. And
> the performance impact should be negligible.
>
> And that's a very simple fix:
>
> -var v: T = ...
> +private val vTLS: ThreadLocal[T] = ...
> +def v = vTLS.get()
> +def v_=(newV: T) = vTLS.set(newV)
and only expose these operations:
def get: Option[S]
def withValue[S](v: T)(f: => S): S = {
val old = local.get()
local.set(v)
try f finally local.set(old)
}
Thanks for the detailed explanation. Now it looks like I understand
the problem. Luckily, all our stuff comes from scala-library.jar and
scala-reflect.jar, so we're only going to prevent the classloader that
works with those from being collected. Is that such big of a problem?
As for API, a big chunk of code in scala-reflect is shared between
reflection and the compiler, so we need a uniform API for those
things.
If we do "set" with the value, how do we make sure that we use that
value (or a closure producing that value) for all threads: present
ones and future ones?
Also, we can't null the value out at the end, because runtime
reflection doesn't have an end. It stems from the same reason that
leads to memory leaks - unlike the compiler, we don't have runs.
scala.reflect.runtime.universe is supposed to be usable from the very
start and till the very end of the application life.
--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-interna...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
I don't think it's that easy. How do you tell apart an entry-point call to isSubType and a recursive call?
Another attempt :)
https://github.com/scalamacros/kepler/blob/a1517ac5929ec58aae71cb3ad91af2f7157625da/src/reflect/scala/reflect/runtime/Tls.scala
Because I cannot. Runtime reflection doesn't know when it should shut down. Do you think that's going to be a problem?
--Viktor Klang
Director of Engineering
It can time itself out, right?
If you're doing this for performance, you shouldn't seek through the map more often than needed:
val v = values.get(currentThread)
if (v.asInstanceOf[AnyRef] == null) { ... }
else v
Also, the way you've done it now will leak nulls if at any point in the future someone changes it to remove keys (if the removal is done after the test and before the get). The way above is safe.
You'll have to make it multiple choice, because I only know one thing that could mean, at least in this context.
Your context is clearly more elaborate/larger than mine, so please outline how that'd work and I'll chime in.
--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-interna...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
Oh, I ruled that out since it needs some sort of timer thread running and updating some shared memory location with every reflection access..
--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-interna...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
--
But the question is, when would you shut that thread down? And that Thread has a reference to reflection...
--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-interna...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
On Thu, Feb 7, 2013 at 9:16 PM, Paul Phillips <pa...@improving.org> wrote:
On Thu, Feb 7, 2013 at 12:03 PM, √iktor Ҡlang <viktor...@gmail.com> wrote:
But the question is, when would you shut that thread down? And that Thread has a reference to reflection...That's the point, it shuts itself down. That is its only purpose. Reflection would start it again if it were loaded again.But now we have introduced a race between shutdown and startup. I'm not saying it's unsolvable, but it's enough complexity to warrant other possible solutions to be explored.
On Thu, Feb 7, 2013 at 3:25 PM, √iktor Ҡlang <viktor...@gmail.com> wrote:
On Thu, Feb 7, 2013 at 9:16 PM, Paul Phillips <pa...@improving.org> wrote:
On Thu, Feb 7, 2013 at 12:03 PM, √iktor Ҡlang <viktor...@gmail.com> wrote:
But the question is, when would you shut that thread down? And that Thread has a reference to reflection...That's the point, it shuts itself down. That is its only purpose. Reflection would start it again if it were loaded again.But now we have introduced a race between shutdown and startup. I'm not saying it's unsolvable, but it's enough complexity to warrant other possible solutions to be explored.
@volatile var threadWatcher = ...
class ThreadWatcher {
...
if (threadWatcher ne this) shutdown()
...
}
--Rex
----
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-interna...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
--Viktor Klang
Director of EngineeringYou received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-interna...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-interna...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
On Thu, Feb 7, 2013 at 9:32 PM, Rex Kerr <ich...@gmail.com> wrote:
On Thu, Feb 7, 2013 at 3:25 PM, √iktor Ҡlang <viktor...@gmail.com> wrote:
On Thu, Feb 7, 2013 at 9:16 PM, Paul Phillips <pa...@improving.org> wrote:
On Thu, Feb 7, 2013 at 12:03 PM, √iktor Ҡlang <viktor...@gmail.com> wrote:
But the question is, when would you shut that thread down? And that Thread has a reference to reflection...That's the point, it shuts itself down. That is its only purpose. Reflection would start it again if it were loaded again.But now we have introduced a race between shutdown and startup. I'm not saying it's unsolvable, but it's enough complexity to warrant other possible solutions to be explored.
@volatile var threadWatcher = ...
class ThreadWatcher {
...
if (threadWatcher ne this) shutdown()
...
}Please post the complete sources, it's hard to discuss correctness of coordination without the full picture.
--Rex
--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-interna...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
Thanks! A promising idea would also be to factor state-dependent and mutually recursive operations such as isSubType/lub/... into a separate object, which could be instatiated on demand and then scrapped once the computation is completed.
--
You received this message because you are subscribed to the Google Groups "scala-internals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-interna...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.