Skip to content

Latest commit

 

History

History
285 lines (174 loc) · 16.6 KB

CG-03-30.md

File metadata and controls

285 lines (174 loc) · 16.6 KB

WebAssembly logo

Agenda for the March 30th video call of WebAssembly's Community Group

  • Where: zoom.us
  • When: March 30th, 4pm-5pm UTC (March 30th, 9am-10am Pacific Time)
  • Location: link on calendar invite

Registration

None required if you've attended before. Send an email to the acting WebAssembly CG chair to sign up if it's your first time. The meeting is open to CG members only.

Logistics

The meeting will be on a zoom.us video conference. Installation is required, see the calendar invite.

Agenda items

  1. Opening, welcome and roll call
    1. Opening of the meeting
    2. Introduction of attendees
  2. Find volunteers for note taking (acting chair to volunteer)
  3. Adoption of the agenda
  4. Proposals and discussions
    1. Review of action items from prior meeting.
    2. Discussion and vote on CG stewardship of the Wasm Discord (Thomas Lively) [10 minutes]
    3. Wasm/JS API integration for ResizableArrayBuffer and GrowableSharedArrayBuffer for phase 1+ (Shu-yu Guo) [20 min]
      1. Poll: Should this go through the phases or a more streamlined process?
    4. Follow-on discussion on irreducible control flow (previous slides) (Conrad Watt) [30 minutes]

Attendees

  • Thomas Trankler
  • Thomas Lively
  • Derek Schuff
  • Zalim Bashorov
  • Sergey Rubanov
  • Ben Titzer
  • Slava Kuzmich
  • Yury Delendik
  • Ross Tate
  • Yuri Iozzelli
  • Chris Fallin
  • Alon Zakai
  • Jay Krell
  • Mano Koukoutos
  • Shravan Narayan
  • Sabine
  • Daniel Wirtz
  • Zhi An Ng
  • Nick Fitzgerald
  • Luke Wagner
  • Paolo Severini
  • Shu-yu Guo
  • Dan Gohman
  • Sam Clegg
  • Dan Weber
  • Andrew Brown
  • Deepti Gandluri
  • Conrad Watt
  • Ryan Hunt
  • Alex Crichton
  • Adam Kelin
  • Arun Purushan
  • Francis McCabe
  • Nabeel Al-Shamma
  • Asumu Takikawa
  • Petr Penzin
  • Emanuel Ziegler
  • Wouter van Oortmerssen
  • Heejin Ahn
  • Rick Battagline
  • Johnny Birch
  • Sean Jensen-Grey
  • Ioanna Dimitriou
  • Richard Winterton
  • Pixel 4a (???)
  • Jacob Abraham
  • Luke Imhoff
  • Paul Dworzanski
  • Jay Krell
  1. Closure

Agenda items for future meetings

None

Schedule constraints

None

Meeting Notes

Discussion and vote on CG stewardship of the Wasm Discord (Thomas Lively) [10 minutes]

NF: How does moderation work now, is that expected to change?

TT: Currently it’s up to me to decide. That’s the main motivation for asking if the CG wants to take it over. We have a CoC that’s similar to others, but currently I have to make the decisions, but I’d feel better if there were a process to handle any incidents that come up. There have only been 2, one was clearly just spam, it was an easy decision. In other, someone was insulting several members of the chat. I appointed one person as a moderator in that case but it would be good if there were clear responsibility

DG: No objections to pointing to the discord channel, it has become a resource for a lot of the community to go to. Maybe we can start with a vote if there are no other discussion items.

DG: quick question for TT, what your team of moderators look like, we can point to this being owned by CG, but no resource to actively monitor this.

TT: at the moment there’s not so much need for a team, there have only been 2 incidents, and I can handle administrative tasks. I’ve appointed a few people who are leaders in nthe community and I trust, but it would be good, if someone isn’t happy with decisions or wants to become a moderator, it would be good to have a clear path to escalate. Someone could talk to the CG, vote on the CoC, etc. It’s a bit more structured. For the question of “how much work is it” , are more moderators needed, it doesn’t seem to be urgent need.

DG: thanks for running the channel so far

FM: Is there scope for using discord as community outreach for wasm from the CG?

TL: it’s already been pretty successful for outreach, we aren’t really looking to change anything right now. Is there something you'd like to see?

FM: at the moment, if you don’t know anyone, it’s probably quite intimidating to reach out to the official CG. As a way of lowering the on-ramp, having a discord channel, Ask-CG-Anything kind of thing.

TL: feels like it already acts like that

TT: a lot of members on the CG actively answer questions there. If there is a need we created channels for more specific discussions. If there is a forum needed, happy to create more channels. An AMA event will be interesting. Couple of proposals are in the pipeline, questions like is it done yet, when will it be done, hard for outsiders to answer. From outside it’s difficult to understand what is happening and what to work on.

TL: Don’t want to spend too much time, should we move to a vote?

DS: Haven’t heard anything in opposition, should we do a consensus vote?

    1. Poll: Should this go through the phases or a more streamlined process?

<SYG Presenting the JS issue, Wasm issue. TODO: Add links>

SG: basically adding 2 new constructors to JS, counterparts to fixed-length array buffer and sharedArrayBuffer, to match the fact that wasm memories can grow, and also to support integration where everytime the memory grows, the existing buffer is detached and remade. So this detaching is a pain for users such as emscripten, where they have to poll or instrument memory accesses where you have to check when you have to invalidate your views. So here you can observe the buffer being grown without making a new one. So the question here is how to integrate with webassembly.memory in the JS API. There’s been discussion in #1292 and #1300 is the actual PR.

The ideas is that we won’t change the .buffer getter; it will still return the buffer. There will be 2 new methods to transition the mode of the memory to surface the fixed or resizable buffer. You can call toResizableBuffer() to get a resizable buffer with the same backing store and detaches any existing buffer. You can transition back and forth this way. If you have a resizable, then the buffer will not detach on growth. If you call the resize method, it will throw if you try to pass an invalid byte length (that would be incompatible with memory.grow). So I’d like to hear technical feedback and discussion, and also, should this be a proposal in its own right that goes through the phases, or should we do something more streamlined?

NA: does this change the behavior of growing the buffer on the Wasm side?

SG: This does not change any behavior on the wasm side, the JS proposal is written in such a way that the API allows for a reserve and commit strategy as well as a realloc strategy - the JS API always requires a max. On the wasm side, if you pass in max, then it is used in the memory constructor otherwise it is implementation defined. But should not be observable. The only think that is observable that the buffer object does not change

CW: we discussed in case where you don’t provide a max length, the JS max should be the web API max length. Did we have any more opinions on that

SG: not on my side, love to hear thoughts here

NF: what is the motivation for old buffer only be detached if you’re switching to a different kind?

SG: Good question, CW also brought this up - my hunch is that I don’t want the aliasing of multiple buffers to the same object, if we were to have an aliasing that is not concurrent… I guess I haven’t thought about it

NF: was imagining the other way, no matter what kind the previous kind was, even when going from resizable to resizable

SG: Amenable to that change, always detaching makes sense

CW: you don’t want to resizable to detach all, you don’t want them to call to resizable and never look at .buffer.

LI: Side topic: What does the % in %IsDetached(..) do? I thought % could only be used for the modulo operator.

SG: In chat, there is no explicit API, imagine I have an internal API that lets me check that.

PP: would it be better to have some param in the memory constructor to turn it into resizable from the get go?

SG: That is extensible, one of my original ideas, not all wasm memories will be created from the JS side, so you will have to have this, one idea is signal intent during construction, but that seems like an overkill for something JS specific.

DS: any thoughts on how to do this procedurally? Not too many changes that are JS-API only changes. Normally we package those with changes to the core spec.

SG: Procedurally, TC39 has a staging model, similar to the phases model for wasm. One of the requests from TC39 before stage 3 is to have integration with the Wasm CG worke dout. That we’re not gating stage 3 on the wasm side. Should the integration PR go through phases? Or once the integration is finalized, to have a nominal change?

CW: motivation for Wasm side for going through phase structure is to make sure we have tests for JS API side before we move it forward.

SG: before we move on to procedural question, any question about technical stuff?

LW: sounds great. A resizable array buffer can’t be transferred via postmessage, can it?

SG: They have the same detach key, so no. Only memory.grow can detach memory array buffers.

DG: CW brought up a good point, want to make sure this has tests, aside of tests, can we do something more lightweight than phases model, we have no precedent, for the delta changes, mostly touching on JS API, we can do something like that

DS: we can poll phase 1, and go directly to phase 3 once we have tests. And shoot for phase 4 around the time it goes through TC39.

SG: sounds like a good suggestion, next TC39 is in less than a month, if we can get some kind of phase advancement, it will be a good signal for TC39, will ask for phase 3, then come back after some implementation work has been done, with tests, and final version of integration PR, further hash out details, something to play with behind a flag.

DS: In the spec repo, we have all these core tests, do we also have JS tests?

ZN: <Yes, we do.>

SG: What do we do when merging with the threads proposal? I don’t know quite how to write the PR for that.

DS: current thread proposal technically still at stage 3…

CW: 2 in fact, we don’t have tests, we need more formal semantics to go to stage 4.

DS: another option to merge this into threads proposal directly

SG: the non-concurrent parts don’t need to be gated on threads proposal. For SharedArrayBuffer parts, the semantics on growing these growable shared array buffers basically designed to be the same across Wasm and JS. We’re both happy with results.

CW: In terms of how we handle the spec, it may make sense to add the non-resizeable parts into the main spec, and then rebase the threads on that.

DS: we do phase 1 today, write some tests, if they are ready in 2 weeks we can poll again to move it along, that should send a clear signal to TC39 that we can fast track the non-concurrent parts

SG: sounds great to me

Poll SF: 14 F: 17 N: A: SA:

Follow-on discussion on irreducible control flow (previous slides) (Conrad Watt) [30 minutes]

<CW Presenting slides>

RT: would like to hear from optimizers/engines, what their perspective is

BT: in V8, the optimizing compiler, not only the reg alloc, the scheduler, both will need to be upgraded to handle irreducible control flow. It would be a pretty substantial amount of work. Reg alloc probably easier than scheduler.

FM: This isn’t full unstructured control flow, this is a nicer target to map unstructured flow to. Not strictly unstructured.

CW: I guess it depends how restrictive your definition is. It can express arbitrary irreducible control flow graphs. But you can argue it’s not “unstructured” in the sense that goto is.

RT: It could be an arbitrary CFG, it doesn’t need to be a multiloop

CW: bikeshedding thing about the name, called it that because of analogy to existing Wasm loop construct.

FM: Multiblock..

CW: Wasm blocks you jump to end, here you jump to start

AZ: What about indirect GOTOs? Would you extend multiloop to support them?

CW: by indirect, do you mean computed? If static, you can use br_table. You’re right that this doesn’t support computed gotos, which are beyond even irreducible control flow.

BT: The problem with computed GOTOs is that you can’t guarantee that you’re using a label is being used in the multiloop construct. Very hard to track them..

CW: this isn’t attempting to express computed GOTO, only about irreducible control flow graphs

BT: would like to see data on how often irreducible control flow shows up, and potential impact. Fil Pizlo has done some experiments, which undoes switch construct, interested to see what performance gap is.

DS: We have some anecdata, when we switched from the fastcomp backend to the new upstream LLVM backend. Conrad mentioned AZ’s relooper paper - the CFG stackify algorithm is the new backend.. When we went to switch the production backend to the new one, we found that most programs have irreducible control flow. It was a noticeable difference so we had to rewrite the irreducible control flow handler.. So there’s evidence that is is there everywhere, also found instances in libc.

YI: cheerp compiler, similar thing, when we implemented stackifier (similar to llvm algorithm), at that time llvm was using unoptimized version, the difference was apparent. If you want some examples of kinds of programs, I remember protobufs autogenerated code, a lot of jumps within a switch in a loop. A lot of improvement in python programs, because of the main loop.

AZ: the big optimization we did in LLVM was actually a bug fix, llvm was identifier things that are reducible as irreducible and generating unnecessary code. Irreducibility is common, it happens in some core libc thing, in musl for example, printf code. Not performance sensitive code, not sure we gained much on benchmarks. The bug fix was a big deal, irreducibility was not a big deal for speed, because critical code tends not to be irreducible, at least on the benchmarks i’ve seen.

AZ: If the main problem is the producer side, we could implement multiloop only on the tools side, we can have cmd line tools that convert multiloop file into something that the VMs can use. This is very interesting at least for the tools side, and I’d be happy to do that work on the tools side.

RT: on local control flow, where every block is its own thing, when you consider exception handling, what happens when multiple blocks share the same handler, you will get a conflict.

CW: at the level of Wasm semantics, the most natural one is, if you have exception within one body, you break out of the multiloop as a whole, and go one level up. Will there be an issue with preserving source level semantics.

RT: The catch might also be a part of the loop, you have to stagger the CFG, that doesn’t solve the problem unfortunately.

TL: thinking of the transformations we have to do to make multiloops with exception handling, seems complicated

AZ: non-nullable locals, some idea for lets rely on shape of blocks, will need to think of how that fits with multiloops, maybe simpler with exceptions

HA: Currently it is possible to place a handler somewhere outside, then we can target the catch handler somewhere outside the loop using delegate. Maybe I’ll look at multiloop more, we haven’t thought about specifics.

CW: also my naive expectation how exception interacts with multi loop. If you have a catch inside a loop, then inside the source program you go to inside of catch, how to translate that into multiloop in a semantic preserving way, might work by putting the catch slightly out, or maybe indirection only in the catch block. Not thought about.

HA: The piece I was thinking about is not that, if you’re jumping into the middle of the catch block.. That I have to think about..

RT: AZ mentioned, there may be a few cases where we have parenthesis that spans multiple blocks, don’t’ work well with multiloop

CW:

ID: are you familiar with common LISP’s TAGBODY go?

CW: No...

ID to post a link on the chat http://clhs.lisp.se/Body/s_tagbod.htm

DS: Are you looking for any particular action from people?

CW: will post issue summarizing discussion, on eh interaction with multiloop, and how would we do performance motivation for this.