This would actually work with the as-is approach as well. The only “downside” (and this is by no means any criticism!!!) is that in my understanding you need to traverse all the different local variables in the function scope as they do not exist as properties of a single object. This has merely performance implications, but doesn’t rule out implementing a hibernate feature like the one below.
Soeren On 28 Jul 2014, at 13:37, Lu Wang <[email protected]> wrote: > I'm not quite sure about the essential difference between your idea and the > current implementation, except for that objects are not supported in asm.js. > Can you show an example with a concrete example? > > > regards, > - Lu > > > On Sun, Jul 27, 2014 at 8:32 PM, Soeren Balko <[email protected]> wrote: > 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 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.
