I have completely forgotten:
I am extremely thankful to Tom Van Cutsem for
https://github.com/tvcutsem/harmony-reflect I have shamelessly taken
some of the copy there.
I am thankful to Ariya Hidayat and Yusuke Suzuki for respectvely esprima
and escodegen which made the test converter easy to write
I am thankful to Mathias Bynens and John-David Dalton for benchmark.js
which made easy to see how I could compare performance-wise.
Le 30/01/2013 21:46, David Bruant a écrit :
Hi,
This idea comes out of the realization that the entire ES5 object
model (property descriptors, [[Extensible]]) can be implemented on top
of POJSO and proxies. What I call POJSO (plain old js object) is an
object which interface is reduced to get/set/has/delete/keys and with
a prototype which is what most people think when they think of objects.
I've decided to try to implement such a thing to see how far I could
go and see if I could get a perf bonus along the way.
I'll be describing here the methodology, limitations, room for
improvement and start a bit of philosophy at the end.
# Methodology
## Code
All the related work can be found at
https://github.com/DavidBruant/HarmonyProxyLab/tree/ES3AndProxy/ES3AndProxy
(specifically the ES5ObjectModelEmul.js file)
## Description of the new objects
### Creating one of these objects
I'm overriding the "Object" built-in with my own version so that "new
Object" creates a proxy (which could be the self-hosted version). If
redefine most Object.* methods to work only with one of these new
objects (and throw on a normal object).
The target of the proxy is an normal object used as a POJSO (which is
kind of the point of the experiment!)
### Property descriptors
Property descriptors are stored in a nested structure:
A weakmap has object as keys and maps as values. Maps have property
names (strings) as keys and the complete property descriptors as
value. Property Descriptors are objects used as POJSO.
### Extensible
A set (ought to be a weakset!) stores all non-extensible objects.
## Conformance
I ported the relevant portion of the test262 test suite (2823 tests).
Since the objects I care to know the conformance of are the ones I
create with "new Object()", I had to mass-convert all relevant tests.
I wrote a tool (/tests/tools/Test262Converter) to do that. The tool
wraps object/array/function literals as well as "new C()" calls to
generate one of my objects using the literal-generated object as target.
I've reached 1630 pass out of 2823. I am too lazy to look at every
single failure, but clicking at some randomly, I see:
* some tests fail because they use a for-in loop or equivalent
(enumeration in second argument of create) and the enumerate trap in
proxies isn't faithfully implemented yet.
* A built-in object (like "Function" or "Date.prototype") is used in
one of the Object.* method and since my test converter doesn't wrap
these, the test just fails.
I know my Object.seal/freeze/isSealed/isFrozen methods aren't
up-to-spec but that's probably the only major non-conformant parts of
my implementation (and that's easy to do)
## Performance
### Time
I created a single micro-benchmark that does Object.defineProperty,
then Object.getOwnPropertyDescriptor to compare how the native version
compares with mine. I'm ~1.5x faster on Aurora on Linux on this very
micro-benchmark (measured by JSPerf)
I won't claim it means I'm way faster because a lot of code path
aren't tested, but that's something promising.
I haven't bothered testing performance of [[Get]] and [[Set]] since
I'm pretty sure I'll be much slower without being able to do anything
about it.
### Memory
No idea how worse I am. Maybe the above time benefit happens at the
expense of memory.
I also have no idea how to measure the difference. I would be
interested if anyone has ideas in this area.
# Room for improvement
If objects were to be self-hosted this way, an hybrid
native/self-hosted would probably yield better results. Also, a
specific construct for property descriptors (instead of generic
objects) would probably see some improvements.
Largely related to recent discussion on es-discuss about performance
characteristics of private symbols against weakmaps, it's almost
certain also that sets/weaksets aren't a good way to represent whether
an object is extensible, but that's the best I had in this instance.
# Thoughts on self-hosting
Forgetting the limitations of the current proxy implementation, I
think I've proven in this experiment that self-hosting the ES5 object
model is possible.
I think this experiment fundamentally asks what the boundary is
between what is part of a core and has to be written in C++ and what
can be self-hosted.
I am nowhere near having an answer to this question, but I think it is
an interesting one.
What are the current thoughts of the JS team on that topic?
Obviously, questions, comments, etc. are more than welcome.
David
_______________________________________________
dev-tech-js-engine-internals mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-js-engine-internals