Bug 164100 - Wasm starts a new stack whenever it adds a new block and has return types for blocks.
Summary: Wasm starts a new stack whenever it adds a new block and has return types for...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Keith Miller
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-10-27 18:08 PDT by Keith Miller
Modified: 2016-11-03 13:58 PDT (History)
4 users (show)

See Also:


Attachments
WIP (17.76 KB, patch)
2016-11-02 13:56 PDT, Keith Miller
no flags Details | Formatted Diff | Diff
Patch (32.68 KB, patch)
2016-11-03 00:15 PDT, Keith Miller
no flags Details | Formatted Diff | Diff
Patch (32.69 KB, patch)
2016-11-03 10:10 PDT, Keith Miller
no flags Details | Formatted Diff | Diff
Patch for landing (32.69 KB, patch)
2016-11-03 12:23 PDT, Keith Miller
no flags Details | Formatted Diff | Diff
Patch for landing (32.77 KB, patch)
2016-11-03 13:34 PDT, Keith Miller
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Keith Miller 2016-10-27 18:08:19 PDT
We do this wrong at the moment.
Comment 1 Keith Miller 2016-11-02 13:56:36 PDT
Created attachment 293693 [details]
WIP
Comment 2 Keith Miller 2016-11-03 00:15:28 PDT
Created attachment 293753 [details]
Patch
Comment 3 JF Bastien 2016-11-03 09:47:22 PDT
Comment on attachment 293753 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=293753&action=review

> Source/JavaScriptCore/ChangeLog:10
> +        return value. Most of the control flow operators needed to be rewritten in able to

"in able to"

> Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp:84
> +        ControlData(Procedure& proc, Type signature, BlockType type, BasicBlock* continuation, BasicBlock* special = nullptr)

What's special?

> Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp:571
> +        entry.expressionStack.append(m_currentBlock->appendNew<VariableValue>(m_proc, B3::Get, Origin(), result));

This can fail, right? I think we should use all the `try` variants everywhere so we soft-fail and bail out.

> Source/JavaScriptCore/wasm/WasmFunctionParser.h:54
> +        ExpressionList expressionStack;

Rename this to avoid the comment above.

> Source/JavaScriptCore/wasm/WasmFunctionParser.h:158
> +        returnValues.append(returnValue);

Same on allocation.

> Source/JavaScriptCore/wasm/WasmFunctionParser.h:314
> +        m_controlStack.append({ WTFMove(m_expressionStack), m_context.addBlock(inlineSignature) });

ditto (and then the other ones below, I'm lazy)

> Source/JavaScriptCore/wasm/WasmValidate.cpp:319
> +    // Think of this as penance for the sin of bad error messages.

?
Comment 4 Mark Lam 2016-11-03 09:48:37 PDT
Comment on attachment 293753 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=293753&action=review

>> Source/JavaScriptCore/ChangeLog:10
>> +        return value. Most of the control flow operators needed to be rewritten in able to
> 
> "in able to"

/rewritten in able to/rewritten to/.

> Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp:132
> +        void makeBlock()
> +        {
> +            ASSERT(type() == BlockType::If);
> +            blockType = BlockType::Block;
> +            special = nullptr;

Why is this assert true?  Seems pretty random.  If the sole purpose of this function is to convert an If ControlData to a Block ControlData, I suggest renaming the function to "convertIfToBlock" or "makeBlockFromIf".  That would make the assertion meaningful.
Comment 5 Keith Miller 2016-11-03 10:09:09 PDT
Comment on attachment 293753 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=293753&action=review

>> Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp:132
>> +            special = nullptr;
> 
> Why is this assert true?  Seems pretty random.  If the sole purpose of this function is to convert an If ControlData to a Block ControlData, I suggest renaming the function to "convertIfToBlock" or "makeBlockFromIf".  That would make the assertion meaningful.

Sure, I'll change it to convertIfToBlock.

>> Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp:571
>> +        entry.expressionStack.append(m_currentBlock->appendNew<VariableValue>(m_proc, B3::Get, Origin(), result));
> 
> This can fail, right? I think we should use all the `try` variants everywhere so we soft-fail and bail out.

Yeah, that's a fair point. I think we should do that in a follow up patch though.

>> Source/JavaScriptCore/wasm/WasmFunctionParser.h:54
>> +        ExpressionList expressionStack;
> 
> Rename this to avoid the comment above.

Fair enough. I changed it to enclosedExpressionStack.
Comment 6 Keith Miller 2016-11-03 10:10:45 PDT
Created attachment 293771 [details]
Patch
Comment 7 Saam Barati 2016-11-03 11:42:32 PDT
Comment on attachment 293771 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=293771&action=review

r=me with a couple comments

> Source/JavaScriptCore/testWasm.cpp:310
> +        Vector<uint8_t> vector = {

It'll be nice once we can make tests not using this API.

> Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp:611
> +    for (size_t i = 0; i < result.size(); ++i)

This loop doesn't look right to me. I think you want to be going from top of stack downwards on both, for result.size() iterations.
Maybe something like:
(unsigned i = 0; i < result.size(); i++) unify(result[result.size() - 1 - i], resultStack[resultStack.size() - 1 - i)

Can you add a test for this?

> Source/JavaScriptCore/wasm/WasmFunctionParser.h:146
> +    RELEASE_ASSERT_NOT_REACHED();

Why is this RELEASE_ASSERT_NOT_REACHED, if it is, maybe the above if (!parseUnreachableExpression(static_cast<OpType>(op))) should be an assertion.

> Source/JavaScriptCore/wasm/WasmFunctionParser.h:476
> +    if (m_expressionStack.size()) {

that makes sense.

> Source/JavaScriptCore/wasm/WasmValidate.cpp:319
> +    // Think of this as penance for the sin of bad error messages.

lol
Comment 8 Keith Miller 2016-11-03 12:10:47 PDT
Comment on attachment 293771 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=293771&action=review

>> Source/JavaScriptCore/testWasm.cpp:310
>> +        Vector<uint8_t> vector = {
> 
> It'll be nice once we can make tests not using this API.

+1

>> Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp:611
>> +    for (size_t i = 0; i < result.size(); ++i)
> 
> This loop doesn't look right to me. I think you want to be going from top of stack downwards on both, for result.size() iterations.
> Maybe something like:
> (unsigned i = 0; i < result.size(); i++) unify(result[result.size() - 1 - i], resultStack[resultStack.size() - 1 - i)
> 
> Can you add a test for this?

Yeah, that's right. It's a little tricky to add a test for this since the only time this is wrong is when the sizes are not equal. The current version of the ML-proto I'm using to generate tests does not support extra stack values. I'll file a bug for it though in the future.

>> Source/JavaScriptCore/wasm/WasmFunctionParser.h:146
>> +    RELEASE_ASSERT_NOT_REACHED();
> 
> Why is this RELEASE_ASSERT_NOT_REACHED, if it is, maybe the above if (!parseUnreachableExpression(static_cast<OpType>(op))) should be an assertion.

We don't want the if to be an assert since it might fail in the validator. Also, every exit from the above loop is a return so unless there is a compiler bug this assert is trivially dead.
Comment 9 Keith Miller 2016-11-03 12:18:22 PDT
(In reply to comment #8)
> Comment on attachment 293771 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=293771&action=review
> 
> >> Source/JavaScriptCore/testWasm.cpp:310
> >> +        Vector<uint8_t> vector = {
> > 
> > It'll be nice once we can make tests not using this API.
> 
> +1
> 
> >> Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp:611
> >> +    for (size_t i = 0; i < result.size(); ++i)
> > 
> > This loop doesn't look right to me. I think you want to be going from top of stack downwards on both, for result.size() iterations.
> > Maybe something like:
> > (unsigned i = 0; i < result.size(); i++) unify(result[result.size() - 1 - i], resultStack[resultStack.size() - 1 - i)
> > 
> > Can you add a test for this?
> 
> Yeah, that's right. It's a little tricky to add a test for this since the
> only time this is wrong is when the sizes are not equal. The current version
> of the ML-proto I'm using to generate tests does not support extra stack
> values. I'll file a bug for it though in the future.

I should note that updating the ml-proto would require changing all the opcode numbers in the existing tests. That would be an unfortunately large amount of work.

> 
> >> Source/JavaScriptCore/wasm/WasmFunctionParser.h:146
> >> +    RELEASE_ASSERT_NOT_REACHED();
> > 
> > Why is this RELEASE_ASSERT_NOT_REACHED, if it is, maybe the above if (!parseUnreachableExpression(static_cast<OpType>(op))) should be an assertion.
> 
> We don't want the if to be an assert since it might fail in the validator.
> Also, every exit from the above loop is a return so unless there is a
> compiler bug this assert is trivially dead.
Comment 10 Keith Miller 2016-11-03 12:23:52 PDT
Created attachment 293786 [details]
Patch for landing
Comment 11 Keith Miller 2016-11-03 13:34:58 PDT
Created attachment 293796 [details]
Patch for landing
Comment 12 Keith Miller 2016-11-03 13:58:54 PDT
Initially committed in r208341: <http://trac.webkit.org/changeset/208341>

Changelog was fixed in r208343: <http://trac.webkit.org/changeset/208343>