Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Increase the table count limit to 100,000 #38

Merged
merged 1 commit into from Jul 7, 2019
Merged

Increase the table count limit to 100,000 #38

merged 1 commit into from Jul 7, 2019

Conversation

lars-t-hansen
Copy link
Contributor

With multi-table we need a common implementation limit for the max number of tables. Firefox uses 100K as the limit currently so that's what I'm proposing here, but it's just a strawman value - please discuss.

@titzer
Copy link

titzer commented Apr 4, 2019

100k sounds OK to me.

@lars-t-hansen
Copy link
Contributor Author

@kmiller68 any objections to this value?

@Horcrux7
Copy link

What this tables all include? If this also includes the vtables of objects/classes then it is usual but very large programs with many small classes can become problems. I see no problems today with it. But software developers tend to ever larger software. With software outside the browser (WASI) and many libraries this limit can be overridden.

Why must there be such a limit?

@binji
Copy link
Member

binji commented Apr 17, 2019

@Horcrux7 The limits are restricted to the JS-API spec. You can see their current values and the purpose of the limits here: https://webassembly.github.io/spec/js-api/index.html#limits

In short, it's to help ensure compatibility across engines.

@Pauan
Copy link

Pauan commented Apr 18, 2019

@Horcrux7 To clarify, a wasm table is basically a huge slab of memory (similar to the linear memory, but for opaque references).

A single table can contain 4,294,967,295 objects.

And you can have 100,000 tables, which means a single wasm module can use 429,496,729,500,000 objects at the same time.

Assuming 32-bit pointers, that's 1,600,000 Gigabytes of RAM, just from the pointers alone (excluding the memory for the objects themself).

At that point, I think you'll have bigger issues than the 100,000 table limit.

@Horcrux7
Copy link

@Pauan A table does not must have its maximum size. In addition, the table does not have to have different objects. There can be only a different order or only one element is different. In the extreme with 100,000 tables you can have only one object. Of course this make no sense. But your calculation also.

If I have a medium table size of 10 then make this for 32 bit pointer 4 Megabytes. This is acceptable for a big fat standalone application with hundreds of megabytes.

@Horcrux7
Copy link

@binji In the list of limits I see 1,000,000 types but only 100,000 tables. If every type need its own vtable then this make no sense for me. I would suggest to use the same limit.

This is just a small vote for a larger limit if no disadvantages occur. I can live well with 100,000.

@Pauan
Copy link

Pauan commented Apr 18, 2019

@Horcrux7 A table does not must have its maximum size.

Yes it does. The table.get and table.set instructions accept i32, so they cannot access more than 2,147,483,647 objects in a single table.

I had made a mistake and thought it was u32. Since I now realize it is i32, the new maximum limits are 214,748,364,700,000 objects per wasm module, which is 800,000 gigabytes of memory for the pointers alone.

In addition, the table does not have to have different objects.

It is completely possible to have different objects in the same table, since the table type can be anyref.

In the extreme with 100,000 tables you can have only one object. Of course this make no sense.

I don't understand at all what you're saying. Perhaps you are completely misunderstanding what a wasm table is?

Like I explained, wasm tables are just a slab of memory (which can contain many things in it). They don't have anything to do with vtables or object types.

You can think of a wasm table as being similar to the heap found in most languages (except the memory is managed by the wasm runtime, not the language).

If I have a medium table size of 10 then make this for 32 bit pointer 4 Megabytes. This is acceptable for a big fat standalone application with hundreds of megabytes.

I explained what the maximum size is. Meaning that a wasm program cannot go higher than that. Obviously you can go lower than that, if you don't need millions of gigabytes of space.

You had said earlier you were concerned about the maximum size, and so I explained that the maximum size is much higher than you thought.

If every type need its own vtable then this make no sense for me. I would suggest to use the same limit.

No... each type does not need its own table. Wasm tables have nothing at all to do with vtables or types.

They are just a storage mechanism, like linear memory, nothing more. You can store millions of vtables and objects in a single wasm table.

As I explained, you can have 800,000 gigabytes of different objects in a wasm program. It is not limited to 100,000 objects, or 100,000 types, or 100,000 vtables.

@binji
Copy link
Member

binji commented Apr 18, 2019

I had made a mistake and thought it was u32. Since I now realize it is i32

It's specified as the i32 value type, but it's used unsigned. So you were right the first time that there are 232 valid table indices.

That said, the JS-API spec also has an implementation-defined limit on the number of table entries: "The maximum size of a table is 10000000."

@Pauan
Copy link

Pauan commented Apr 18, 2019

@binji It's specified as the i32 value type, but it's used unsigned. So you were right the first time that there are 2^32 valid table indices.

Ah, okay, great.

That said, the JS-API spec also has an implementation-defined limit on the number of table entries: "The maximum size of a table is 10000000."

Right, so for JS specifically the limit would be 1,000,000,000,000 references, which is 3,725 gigabytes for the pointers alone.

@Horcrux7
Copy link

@Pauan Perhaps you are completely misunderstanding what a wasm table is?

This can be right. I have write it in my first post. Currently I does not use it in my compiler (Java bytecode to wasm).

Like I explained, wasm tables are just a slab of memory (which can contain many things in it). They don't have anything to do with vtables or object types.
You can use it for many things. This is clear. I had plan to use for every vtable to use a single table of functions. In the constructor of an object then I have only to assign the table. I will start in some weeks with this stuff.

If you think this is a bad idea then forget all what I have write.

@Pauan
Copy link

Pauan commented Apr 20, 2019

I had plan to use for every vtable to use a single table of functions. In the constructor of an object then I have only to assign the table.

That doesn't sound very good to me. You can't actually store tables into objects, because tables aren't a first-class value in wasm.

I don't know what your compiler architecture is, but it seems to me that the right thing to do is:

  1. Have a single table with type anyfunc.

  2. Put all the vtable functions into that single table (even for different vtables).

  3. The vtables are stored in linear memory, and they would just be a vector of indexes (the indexes are the location of the function within the table).

  4. The constructor would assign the pointer to the vtable into the object.

  5. When calling a Java method, it would lookup the vtable pointer in the object, then lookup the index in the appropriate vtable slot (by shifting the vtable pointer), and then use call_indirect (with the index) to call the function.

Basically, treat tables like a heap (or the linear memory): you have a single table with many things in it, and you store table indexes (which are basically pointers).

If you need multiple tables, you're likely doing something wrong (there are exceptions to that, of course).

Also keep in mind that right now browsers only support 1 table anyways, so technically right now the table limit is 1. So if you care about older browsers you'll need to use 1 table anyways.

@Horcrux7
Copy link

@Pauan Many thanks for your explanation. I will pay attention to it.

The features of current browsers are not the problem. I need the GC feature anyway.

@rossberg
Copy link
Member

@Horcrux7, if you plan to use GC objects anyway, why would you still use tables?

@Horcrux7
Copy link

@rossberg I need tables of type function for call_indirect. My understand is that this is only possible via tables.

@rossberg
Copy link
Member

The GC proposal (or more accurately, the typed function reference proposal it now builds upon) includes a call_ref instruction to invoke a function through a typed reference directly. Unless you need the dynamic typing of call_indirect, there hopefully is little reason to use it in such a setting.

@Horcrux7
Copy link

@rossberg If this feature will be available in any implementation in a (far) future then I can look into it.

@titzer
Copy link

titzer commented Apr 29, 2019

One valid use case that we have discussed in the past is to narrow the type of a table to a specific function type; so instead of anyfunc, we could have a table hold functions of type (i32, i32) -> i32. Such homogenously typed function tables can be implemented with a static (rather than dynamic) a signature check. Some language implementations can benefit from such tables; e.g. if the class hierarchy is known statically, vtables can be transposed into mtables which are indexed by class ID.

(E.g. https://github.com/titzer/virgil uses this in its native and wasm targets, but currently the mtables are stored in memory in the wasm target, and the entries are indices into the one large function table. It would be a performance improvement to use multiple, typed tables here in the future, to avoid a signature check and additional memory accesses. AFAICT at this point, the mtable implementation will still be faster than typed vtables in the GC proposal.)

@lars-t-hansen
Copy link
Contributor Author

@binji, can you merge this?

@binji binji merged commit aa596e5 into WebAssembly:master Jul 7, 2019
pull bot pushed a commit to Richienb/v8 that referenced this pull request Jul 8, 2019
Update for a recent spec change: WebAssembly/reference-types#38

R=binji@chromium.org

Bug: v8:7581
Change-Id: I4ac4a4c351dfc100f978e1aead308cbed59149e4
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1690832
Reviewed-by: Ben Smith <binji@chromium.org>
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62576}
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants