The j.l.instrument agent implementation doesn't allow you to add new field
(there is a patch for that in mlvm repository)
just to modify the content of any methods.

So it's possible but you have to introduce an indirection
between an instance and its fields.
Modern processors doesn't like this kind of indirections (instance.fields.x)
so it will be slow, slower than V8.

Rémi

On 05/10/2011 03:05 AM, Charles Oliver Nutter wrote:
It would work, but would rarely be applicable for production code.
Better is to do what JVM does and mark the previous revision of the
hidden class as "not entrant", and then new entries into that call
path will use the newer code.

I'm very excited to see Rhino getting updated. It is an embarrassment
that the JVM can't run JavaScript as fast as V8. I'd love to help, if
there's something I can do...I have looked at Rhino's codebase in the
past and know the general lay of the land.

- Charlie

On Mon, May 9, 2011 at 10:00 AM, MLeo<[email protected]>  wrote:
Strange idea, couldn't someone use a java agent to rewrite a class on the
fly for this purpose? Or does that have extreme performance penalties?

On 9 May 2011 16:38, "Rémi Forax"<[email protected]>  wrote:
On 05/06/2011 02:54 PM, Hannes Wallnoefer wrote:
2011/5/6 Rémi Forax<[email protected]>:
On 05/06/2011 12:39 PM, Hannes Wallnoefer wrote:

The reason I'll probably not start from John's branch directly is it
is based on invokedynamic from the ground up, and we need to support
Java 6 and earlier for the foreseeable future.

As for type inference, specialization etc.: that is certainly
interesting, but right now property access seems to be the most
significant bottleneck, so it seems like a good idea to target that
first.

Hannes
I can agree about property access being a bottleneck
but for me to solve property access you need type profiling
which is the common ground for type inference and type
specialization too.

Let me explain how property access problem can be solved.
As usual, you need an assumption, mine is that any instances
created at one allocation site will have the same set of properties,
i.e the same class.

So in the interpreter, each allocation site has a reified object
corresponding to that allocation site (in my implementation, I
reuse j.l.invoke.CallSite but it's a detail).
When the interpreter creates an object (a hash map because
in the interpreter we don't have enough information) it
also stores the allocation site.
The idea is that the reified object corresponding to the allocation
site can be considered as describing the class of the instance.

Each time, there is a lookup in the hashmap that correspond to
a property that was not seen before, the allocation site object
of the instance is updated to say that when optimized, the class
should have the property. If the property already exist, I keep
the class of the value stored (which is equivalent to profiling
the runtime type of the property).

When the code containing the allocation site needs to be compiled
because it's a hot code, a new class containing all the properties
of the allocation site is generated and used to create the instance.
The class is also used by the inference algorithm to avoid to
generate guards if not needed.

In fact, it's a little more complex. First, the generated class also own
a field named data which is used as an optimized hashmap if an instance
is used in a code that was never used before and this code adds
dynamically
a new property to that instance.
Here, perhaps it could be great to update the allocation site object,
currently I don't do that.
Second, instead of creating a class for each allocation site, I try to
see
if an already
generated class for another allocation site doesn't match.
Here, I do the lookup only when I need to generate the code, it should
be
done before
because if you have a property with the same name but two different
profiled
types,
I will never generate one class but two versions of the same class.
A way to reuse the same class is to take a look to callsites where the
instance are used.
If two instances of different allocation site are used at the same
callsite
and have
the same property names, then it should be the same class.

As you see, you first need to profile variables, callsites and
allocations
sites
before being able to optimize.
Thanks for the detailed explanation, Rémi. Rhino in its current form
is a bit different from what you describe in that it runs in either
interpreted or compiled-to-bytecode mode but doesn't profile and
selectively compile hot code.

My plan, and what John implemented in the davincimonkey branch, is to
use a generic struct-like class that stores values in generic fields
or an array. A hidden class (maybe "layout" is the better term, as
these are not Java classes) simply maps the actual property names to
these generic slots, so a callsite can directly access that slot
provided the cached layout/hidden class matches that of the actual
object.

The way hidden classes/layouts are managed (and AFAIK this is also the
way it's implemented in V8) is by recording their evolution paths:
each time a property is assigned that is not part of the class, a new
hidden class is created along with a reference from the old one. If a
hidden class/layout already exists for a property you can immediately
walk down the layout graph until it ends or forks to reduce the number
of layout switches.
But the JVM is not V8. V8 can mutate the class,
instead of doing a single pointer comparison [1], the JVM will do 3
comparisons:
- one is done by the current implementation of invokedynamic (will be
removed in the future)
- another is done to test the class (Object is different from String
or Double)
- another is done to check the layout.

BTW, someone can explain me how the size of the instance grows with V8
without calling the GC ?

So I agree that hidden classes provide a good base on which to
implement profiling and optimizations that build on top of it, but
Rhino is missing a few other requirements to make that happen in the
near future.

Hannes
Rémi

[1] http://code.google.com/apis/v8/design.html

Rémi

--
You received this message because you are subscribed to the Google
Groups
"JVM Languages" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/jvm-languages?hl=en.


--
You received this message because you are subscribed to the Google Groups
"JVM Languages" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/jvm-languages?hl=en.

--
You received this message because you are subscribed to the Google Groups
"JVM Languages" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/jvm-languages?hl=en.


--
You received this message because you are subscribed to the Google Groups "JVM 
Languages" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/jvm-languages?hl=en.

Reply via email to