Coming to think of this: I think that making the function scopes in call stacks explicit in dedicated objects that are managed in the emscripten HEAP had other advantages:
For example, by introducing an asynchronous call "emscripten_hibernate_if_requested" similar to "emscripten_sleep" at the entry to every function (or even more frequently if a lot of CPU cycles are spent in a single function), one could relatively easily implement a "hibernate" feature. The "emscripten_hibernate_if_requested" would essentially asynchronously check whether the user (or some external component) has requested the application to hibernate (e.g., into some persistent storage like IndexedDB). If so, "emscripten_hibernate_if_requested" would store the local variable states in the "funcScope" chain, store the ArrayBuffer underlying the HEAPx arrays and other global state (STACKTOP, etc.). Recovering from the hibernated state was then very easy and meant re-instating the stored global and local state and calling the callback of "emscripten_hibernate_if_requested". This was really, really useful in a lot of situations. The only downside I see was that in an extreme case, *all* functions had to be "asyncified". Perhaps this could be relaxed when there is frequently called a main loop (like in graphics-intense applications like games) already, when only the state of the main loop had to be hibernated. On Monday, July 28, 2014 10:35:20 AM UTC+10, Soeren Balko wrote: > > The only think I am not sure about is whether asm.js allows objects as > local variables. My take on the specification ( > http://asmjs.org/spec/latest/) is that it does, in fact, not support this > - the asm.js type system is fairly restrictive. However, heap pointers are > obviously supported and so is access to the heap or stack at a certain > pointer plus offset. Basically, one had to apply the same rule with which a > local struct variable is currently mapped. I strongly suspect it becomes a > heap or stack pointer. > > I just checked what emscripten does to represent the following function: > > static void foo(int a, float b) { > struct { > int a; > float b; > } bar; > > bar.a = a; > bar.b = b; > > printf("%i %f\n", bar.a, bar.b); > } > > It becomes this asm.js Javascript function: > > function _foo($a,$b) { > $a = $a|0; > $b = +$b; > var $0 = 0, $1 = 0.0, $2 = 0, $3 = 0.0, $4 = 0, $5 = 0, $6 = 0, $7 = 0.0, > $8 = 0.0, $bar = 0, $vararg_buffer = 0, $vararg_ptr1 = 0, label = 0, sp = 0; > *sp = STACKTOP;* > STACKTOP = STACKTOP + 32|0; > $vararg_buffer = sp; > * $bar = sp + 16|0;* > * $0 = $a;* > * $1 = $b;* > * $2 = $0;* > * HEAP32[$bar>>2] = $2;* > * $3 = $1;* > * $4 = (($bar) + 4|0);* > * HEAPF32[$4>>2] = $3;* > $5 = HEAP32[$bar>>2]|0; > $6 = (($bar) + 4|0); > $7 = +HEAPF32[$6>>2]; > $8 = $7; > HEAP32[$vararg_buffer>>2] = $5; > $vararg_ptr1 = (($vararg_buffer) + 4|0); > > > HEAPF64[tempDoublePtr>>3]=$8;HEAP32[$vararg_ptr1>>2]=HEAP32[tempDoublePtr>>2];HEAP32[$vararg_ptr1+4>>2]=HEAP32[tempDoublePtr+4>>2]; > (_printf((8|0),($vararg_buffer|0))|0); > STACKTOP = sp;return; > } > > I have highlighted the interesting lines where the “bar" struct is > essentially copied to a location in memory, pointed to by STACKTOP+16 and > the function parameters $a and $b are assigned to the struct members > (residing at the memory locations pointed to be $bar and $bar+4, > respectively). Interestingly, emscripten uses the artificial stack (HEAP32 > array at STACKTOP offset) for certain variables (such as structs and the > vararg parameters for the printf call), whereas any variable that can be > directly represented as a local variable (such as $a and $b) stays a local > variable of the Javascript function. > > Coming back to the problem of efficiently saving and restoring local > variables, my understanding is that you would need to save 16 local > variables ($a, $b, $0 … $8, $bar, $vararg_buffer, $vararg_ptr1, label, sp). > Some of these would probably be eliminated by better optimisation settings > (like $2, $3, $4), but you may still end up with a whole lot of local > variables to be taken care of. If you elevated all of the local variables > to struct members like proposed before, you would in principle have fewer > work to do for saving and restoring them. However, each access would turn > into a HEAP32[(funcScopePtr + variableOffset|0)>>2] operation. I would > *guess* that the performance implications are next to nothing (at the least > in an AOT asm.js runtime). > > Soeren > > On 28 Jul 2014, at 9:58, Lu Wang <[email protected]> wrote: > > AFAIK, this is not allowed in asm.js. > Usually I understand asm.js as an almost truly assembly language. > > regards, > - Lu > > > On Sun, Jul 27, 2014 at 4:44 PM, Sören Balko <[email protected]> wrote: > >> Thanks for clarifying this for me - can’t wait to try it out. That’s >> definitely one of the most exciting new features in Emscripten! >> >> In terms of saving and restoring local variables quickly: to avoid >> iterating over all variables, can you make them properties of an object at >> compile time (instead of atomic variables in the function scope)? I other >> words, make the function scope explicitly accessible as an object? For >> example, for two the functions below: >> >> void foo(int a) { >> float b; >> char * c; >> … >> bar(b); >> ... >> } >> >> void bar(float c) { >> int d; >> … >> emscripten_sleep(1); >> … >> } >> >> You could generate two explicit scope objects: >> >> fooScope = { >> parentScope: ... >> a: ... >> b: … >> c: … >> } >> >> and >> >> barScope = { >> parentScope: … >> c: … >> d: ... >> } >> >> When saving the local variables when calling emscripten_sleep, you merely >> had to store barScope. If bar was called from foo, its parentScope property >> was set to fooScope (this had to happen at runtime at a small cost). >> Restoring the scope is again, a single operation only. In return, the >> affected functions would need to access their variables as properties of >> the funcScope object. Not sure if asm.js allows for that. You would >> probably have to represent the scope structures on the heap and turn >> accesses to the local variables into heap accesses at some offset of the >> scope struct location. Also, the funcScope.parentScope property had to be >> populated when entering a function. So there was a trade-off, not sure how >> it would pan out. >> >> Soeren >> >> >> On 27 Jul 2014, at 22:29, 王璐 <[email protected]> wrote: >> >> Hi, >> >> There are definitely overhead for this transformation, mainly saving and >> restoring local variables. Usually this kind of overhead is acceptable, as >> async functions are usually supposed to be slow. >> >> On the other hand, how would you define 'performance degration', as >> probably we don't have other options. >> >> asm.js does support function pointers, although you need to know the >> signature, and asyncify is asm.js compliant. In fact asm.js is required for >> this feature. >> >> >> regards, >> - Lu >> >> -- >> You received this message because you are subscribed to a topic in the >> Google Groups "emscripten-discuss" group. >> To unsubscribe from this topic, visit >> https://groups.google.com/d/topic/emscripten-discuss/kSMH2N0CoLg/unsubscribe >> . >> To unsubscribe from this group and all its topics, send an email to >> [email protected]. >> For more options, visit https://groups.google.com/d/optout. >> >> >> >> >> >> -- >> You received this message because you are subscribed to a topic in the >> Google Groups "emscripten-discuss" group. >> To unsubscribe from this topic, visit >> https://groups.google.com/d/topic/emscripten-discuss/kSMH2N0CoLg/unsubscribe >> . >> To unsubscribe from this group and all its topics, send an email to >> [email protected]. >> For more options, visit https://groups.google.com/d/optout. >> > > > -- > You received this message because you are subscribed to a topic in the > Google Groups "emscripten-discuss" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/emscripten-discuss/kSMH2N0CoLg/unsubscribe > . > To unsubscribe from this group and all its topics, send an email to > [email protected]. > For more options, visit https://groups.google.com/d/optout. > > > Soeren Balko, PhD > Founder & Director > zfaas Pty Ltd > Brisbane, QLD > Australia > > > > -- You received this message because you are subscribed to the Google Groups "emscripten-discuss" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
