Skip to content

Latest commit

 

History

History
74 lines (45 loc) · 5.76 KB

04-29.md

File metadata and controls

74 lines (45 loc) · 5.76 KB

April 29, 2021 Incubator Call Notes (Resizable buffers)

Attendees:

  • Shu-yu Guo (SYG)
  • Jordan Harband (JHD)
  • Peter Hoodie (PHE)
  • Yulia Startsev (YSV)
  • Dan Ehrenberg (DE)
  • Shane Carr (SFC)

Notes

SYG: Presenting the current status of the proposal, issue #40 3 ways to side step creating a new constructor:

  1. Overloading (second parameter) (Twitter poll didn’t like this one)
  2. Overloading (second parameter is an options bag) (Twitter poll liked this the most)
  3. Array.resizable(...) which would return a resizable array buffer

Any preference here for 1?

PHE: Options bags are a bit of an issue as there is a throw away object. Ideally not, but here it shouldn’t be a problem

SYG: main problem might be web compat. It tests that certain values are ignored in the array buffer constructor. Engine specific test Non-zero chance that something might throw

JHD: will be hard to argue against the options bag pattern after temporal

SYG: preference for 2 it looks like. Options bags have a smaller possibility of web incompatibility

JHD: not convinced by the argument for arraybuffer.resizable being like from, it can’t be simulated by calling new ArrayBuffer.

SYG: thats a compelling argument to me, because in my own code when I have that pattern I usually make the constructor private and make a static method for each case. Since we don’t have arrayBuffer.fixedLength() this would be a one-off.

JHD: to moddables concern, its pretty common to have options bags, and it should be optimizable?

SYG: that optimization is pretty hard for the baseline compilation. When you can do escape analysis, and inline all the way down, it is possible. But not at an earlier optimization phase like baseline. The answer here is usually generational gc

PHE: I would agree. It isn’t a huge issue to have an options bag here. I would be concerned if they migrated elsewhere. I am a bit concerned with the general pushback we get when we say that we have a different implementation and different needs, and not the same things can be optimized.

YSV: we had a gentle preference here, arraybuffer.resizable > ResizableArrayBuffer > ArrayBuffer(..) but it is largely about how it communicates the resizability

SYG: we can bikeshed a bit here on the options bag’s naming, ie maxResizableByteLength or similar (may be a bit long).

SFC: we shouldn’t say that we just follow options bag due to intl or temporal. In this case, the options bag changes the behavior of the object, whereas previously the changes have been small to medium modifications on objects. This is a discussion I would like to have.

DE: if you look at how options bags are used on the web platform, and while not all js is on the web, most js developers are familiar with that host. In web platform, options bags do change the underlying class significantly, so I think there is precedent. Jordan might know more about what the case is in the js ecosystem.

JHD: I wasn’t there for es6 decisions, but arguably some of those should have been options bags.

SFC: One area where this might have implications is TypeScript. How does TypeScript detect that an options bag is modifying the type? You can’t always tell statically.

SYG: this TypeScript argument was also brought up initially with the original proposal, due to how it changes the backing buffer for typed arrays. The answer here is that they don’t do it. I do take your point that “here is a method that will always throw when it is not resizable”. The way I’ve squared this in my mind is, the existing methods on the array buffer, also apply here. In terms of the byte signature is the conditional or unconditional depending on something. We might say that fixed size buffers are a restricted case.

SFC: Ok, this is convincing to me

SYG: I agree with your point regarding the changing of the type on a high level though. In this case it worked out, and people -- internally at least -- seem to like it. But for something that significantly changes a type.

<everyone seems happy with option 2>

SYG: During V8's implementation we discovered a spec bug where racing grows on growable SABs have bad behavior, see #39 for description and #42 for fix. The high level idea of the fix is that we provide a global total ordering to all grows.

JHD: The example in #39 with grow(20) and grow(40) points out grows can have two different intents: 1) that I care about the end state of growing to size 40, 2) I also care about the initial precondition that the original length was 10.

SYG: The spec fix allows implementations to implement either behavior. The main reasons I gave implementations this latitude are: You really shouldn't be racing your grows. We gotta fully spec it out because there's no UB on the web, but if you're racing your grows without manual synchronization something's probably wrong. The two differences are hard to distinguish in this case on the language side. If a grow fails due to the original precondition failing, it could've been due to some concurrency nondeterminism, or some intermediate allocation failure. Specifically, the implementation latitude is that publishing the new length can be done either via a single CAS (i.e. fail early) or CAS in a loop (i.e. built-in retries when there's a race).

PHE: You may want to ping the Agoric folks to get their thoughts on the implementation choice.

SYG: Will do, I suspect it's fine because this doesn't really let you observe anything useful about the implementation, nor am I sure it's even possible to observe anything additional to the existing concurrency nondeterminism.

PHE: Agree it's minor, but good to give them a heads up.