Skip to content
Permalink
Browse files
[JSC] Add @throwXXXError bytecode intrinsic
https://bugs.webkit.org/show_bug.cgi?id=162995

Reviewed by Saam Barati.

Source/JavaScriptCore:

Builtin JS code need to check arguments carefully since it is somewhat standard library for JS.
So bunch of `throw new @TypeError("...")` exists while usual code does not have so many.
However the above code bloats 32 instructions per site, enlarges the size of bytecodes of builtins,
and prevent us from inlining. We should have a way to reduce this size.

Fortunately, we already have such a opcode: op_throw_static_error. In this patch,
1. We extends op_throw_static_error to throw arbitrary errors. Previously, only TypeError and ReferenceError are allowed.
   We can embed ErrorType enum in op_throw_static_error to throw any types of errors.
2. We introduce several new bytecode intrinsics, `@throwTypeError("...")`, `@throwRangeError("...")`,
   and `@throwOutOfMemoryError()`. And use it inside builtin JS instead of `throw new @TypeError("...")` thingy.
3. DFG Node for throw_static_error is incorrectly named as "ThrowReferenceError". This patch renames it to "ThrowStaticError".

* builtins/ArrayConstructor.js:
* builtins/ArrayIteratorPrototype.js:
(next):
* builtins/ArrayPrototype.js:
(values):
(keys):
(entries):
(reduce):
(reduceRight):
(every):
(forEach):
(filter):
(map):
(some):
(fill):
(find):
(findIndex):
(includes):
(sort):
(concatSlowPath):
(copyWithin):
* builtins/DatePrototype.js:
(toLocaleString.toDateTimeOptionsAnyAll):
(toLocaleString):
(toLocaleDateString.toDateTimeOptionsDateDate):
(toLocaleDateString):
(toLocaleTimeString.toDateTimeOptionsTimeTime):
(toLocaleTimeString):
* builtins/FunctionPrototype.js:
(bind):
* builtins/GeneratorPrototype.js:
(globalPrivate.generatorResume):
* builtins/GlobalOperations.js:
(globalPrivate.speciesConstructor):
* builtins/MapPrototype.js:
(forEach):
* builtins/ModuleLoaderPrototype.js:
(provide):
* builtins/ObjectConstructor.js:
(values):
(entries):
(assign):
* builtins/PromiseConstructor.js:
(race):
(reject):
(resolve):
* builtins/PromiseOperations.js:
(globalPrivate.newPromiseCapability.executor):
(globalPrivate.newPromiseCapability):
(globalPrivate.initializePromise):
* builtins/PromisePrototype.js:
* builtins/ReflectObject.js:
(apply):
(deleteProperty):
(has):
* builtins/RegExpPrototype.js:
(globalPrivate.regExpExec):
(match):
(replace):
(search):
(split):
(intrinsic.RegExpTestIntrinsic.test):
* builtins/SetPrototype.js:
(forEach):
* builtins/StringConstructor.js:
(raw):
* builtins/StringIteratorPrototype.js:
(next):
* builtins/StringPrototype.js:
(match):
(globalPrivate.repeatSlowPath):
(repeat):
(padStart):
(padEnd):
(intrinsic.StringPrototypeReplaceIntrinsic.replace):
(localeCompare):
(search):
(split):
* builtins/TypedArrayConstructor.js:
(of):
(from):
* builtins/TypedArrayPrototype.js:
(globalPrivate.typedArraySpeciesConstructor):
(every):
(find):
(findIndex):
(forEach):
(some):
(subarray):
(reduce):
(reduceRight):
(map):
(filter):
* bytecode/BytecodeIntrinsicRegistry.h:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitThrowStaticError):
(JSC::BytecodeGenerator::emitThrowReferenceError):
(JSC::BytecodeGenerator::emitThrowTypeError):
(JSC::BytecodeGenerator::emitThrowRangeError):
(JSC::BytecodeGenerator::emitThrowOutOfMemoryError):
(JSC::BytecodeGenerator::emitReadOnlyExceptionIfNeeded):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::BytecodeIntrinsicNode::emit_intrinsic_throwTypeError):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_throwRangeError):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_throwOutOfMemoryError):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNodeType.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_throw_static_error):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_throw_static_error): Deleted.
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL): Deleted.
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter.asm:
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
* runtime/Error.cpp:
(JSC::createError):
(WTF::printInternal):
* runtime/Error.h:

LayoutTests:

* js/Object-assign-expected.txt:

Canonical link: https://commits.webkit.org/180906@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@206853 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Constellation committed Oct 6, 2016
1 parent 0d0e2e0 commit 83cc606852f80b90e136e96093adc68c67e03fed
Showing 52 changed files with 465 additions and 184 deletions.
@@ -1,3 +1,12 @@
2016-10-05 Yusuke Suzuki <utatane.tea@gmail.com>

[JSC] Add @throwXXXError bytecode intrinsic
https://bugs.webkit.org/show_bug.cgi?id=162995

Reviewed by Saam Barati.

* js/Object-assign-expected.txt:

2016-10-05 Wenson Hsieh <wenson_hsieh@apple.com>

Introduce InputEvent bindings in preparation for the input events spec
@@ -6,9 +6,9 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
PASS Object.assign.length is 2
PASS Object.assign.name is 'assign'
check TypeError on null/undefined
PASS Object.assign() threw exception TypeError: can't convert undefined to object.
PASS Object.assign(undefined) threw exception TypeError: can't convert undefined to object.
PASS Object.assign(null) threw exception TypeError: can't convert null to object.
PASS Object.assign() threw exception TypeError: Object.assign requires that input parameter not be null or undefined.
PASS Object.assign(undefined) threw exception TypeError: Object.assign requires that input parameter not be null or undefined.
PASS Object.assign(null) threw exception TypeError: Object.assign requires that input parameter not be null or undefined.
PASS var target = {}, ret = Object.assign(target); target === ret is true
multiple sources are copied
PASS var target = {}, ret = Object.assign(target, {a: 1}); target === ret is true
@@ -1,3 +1,170 @@
2016-10-05 Yusuke Suzuki <utatane.tea@gmail.com>

[JSC] Add @throwXXXError bytecode intrinsic
https://bugs.webkit.org/show_bug.cgi?id=162995

Reviewed by Saam Barati.

Builtin JS code need to check arguments carefully since it is somewhat standard library for JS.
So bunch of `throw new @TypeError("...")` exists while usual code does not have so many.
However the above code bloats 32 instructions per site, enlarges the size of bytecodes of builtins,
and prevent us from inlining. We should have a way to reduce this size.

Fortunately, we already have such a opcode: op_throw_static_error. In this patch,
1. We extends op_throw_static_error to throw arbitrary errors. Previously, only TypeError and ReferenceError are allowed.
We can embed ErrorType enum in op_throw_static_error to throw any types of errors.
2. We introduce several new bytecode intrinsics, `@throwTypeError("...")`, `@throwRangeError("...")`,
and `@throwOutOfMemoryError()`. And use it inside builtin JS instead of `throw new @TypeError("...")` thingy.
3. DFG Node for throw_static_error is incorrectly named as "ThrowReferenceError". This patch renames it to "ThrowStaticError".

* builtins/ArrayConstructor.js:
* builtins/ArrayIteratorPrototype.js:
(next):
* builtins/ArrayPrototype.js:
(values):
(keys):
(entries):
(reduce):
(reduceRight):
(every):
(forEach):
(filter):
(map):
(some):
(fill):
(find):
(findIndex):
(includes):
(sort):
(concatSlowPath):
(copyWithin):
* builtins/DatePrototype.js:
(toLocaleString.toDateTimeOptionsAnyAll):
(toLocaleString):
(toLocaleDateString.toDateTimeOptionsDateDate):
(toLocaleDateString):
(toLocaleTimeString.toDateTimeOptionsTimeTime):
(toLocaleTimeString):
* builtins/FunctionPrototype.js:
(bind):
* builtins/GeneratorPrototype.js:
(globalPrivate.generatorResume):
* builtins/GlobalOperations.js:
(globalPrivate.speciesConstructor):
* builtins/MapPrototype.js:
(forEach):
* builtins/ModuleLoaderPrototype.js:
(provide):
* builtins/ObjectConstructor.js:
(values):
(entries):
(assign):
* builtins/PromiseConstructor.js:
(race):
(reject):
(resolve):
* builtins/PromiseOperations.js:
(globalPrivate.newPromiseCapability.executor):
(globalPrivate.newPromiseCapability):
(globalPrivate.initializePromise):
* builtins/PromisePrototype.js:
* builtins/ReflectObject.js:
(apply):
(deleteProperty):
(has):
* builtins/RegExpPrototype.js:
(globalPrivate.regExpExec):
(match):
(replace):
(search):
(split):
(intrinsic.RegExpTestIntrinsic.test):
* builtins/SetPrototype.js:
(forEach):
* builtins/StringConstructor.js:
(raw):
* builtins/StringIteratorPrototype.js:
(next):
* builtins/StringPrototype.js:
(match):
(globalPrivate.repeatSlowPath):
(repeat):
(padStart):
(padEnd):
(intrinsic.StringPrototypeReplaceIntrinsic.replace):
(localeCompare):
(search):
(split):
* builtins/TypedArrayConstructor.js:
(of):
(from):
* builtins/TypedArrayPrototype.js:
(globalPrivate.typedArraySpeciesConstructor):
(every):
(find):
(findIndex):
(forEach):
(some):
(subarray):
(reduce):
(reduceRight):
(map):
(filter):
* bytecode/BytecodeIntrinsicRegistry.h:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitThrowStaticError):
(JSC::BytecodeGenerator::emitThrowReferenceError):
(JSC::BytecodeGenerator::emitThrowTypeError):
(JSC::BytecodeGenerator::emitThrowRangeError):
(JSC::BytecodeGenerator::emitThrowOutOfMemoryError):
(JSC::BytecodeGenerator::emitReadOnlyExceptionIfNeeded):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::BytecodeIntrinsicNode::emit_intrinsic_throwTypeError):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_throwRangeError):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_throwOutOfMemoryError):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNodeType.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_throw_static_error):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_throw_static_error): Deleted.
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL): Deleted.
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter.asm:
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
* runtime/Error.cpp:
(JSC::createError):
(WTF::printInternal):
* runtime/Error.h:

2016-10-05 Yusuke Suzuki <utatane.tea@gmail.com>

Unreviewed, attempt to fix CLoop build after r206846
@@ -47,19 +47,19 @@ function from(items /*, mapFn, thisArg */)

if (mapFn !== @undefined) {
if (typeof mapFn !== "function")
throw new @TypeError("Array.from requires that the second argument, when provided, be a function");
@throwTypeError("Array.from requires that the second argument, when provided, be a function");

if (arguments.length > 2)
thisArg = arguments[2];
}

if (items == null)
throw new @TypeError("Array.from requires an array-like object - not null or undefined");
@throwTypeError("Array.from requires an array-like object - not null or undefined");

var iteratorMethod = items.@iteratorSymbol;
if (iteratorMethod != null) {
if (typeof iteratorMethod !== "function")
throw new @TypeError("Array.from requires that the property of the first argument, items[Symbol.iterator], when exists, be a function");
@throwTypeError("Array.from requires that the property of the first argument, items[Symbol.iterator], when exists, be a function");

var result = @isConstructor(thisObj) ? new thisObj() : [];

@@ -29,11 +29,11 @@ function next()
"use strict";

if (this == null)
throw new @TypeError("%ArrayIteratorPrototype%.next requires that |this| not be null or undefined");
@throwTypeError("%ArrayIteratorPrototype%.next requires that |this| not be null or undefined");

let next = this.@arrayIteratorNext;
if (next === @undefined)
throw new @TypeError("%ArrayIteratorPrototype%.next requires that |this| be an Array Iterator instance");
@throwTypeError("%ArrayIteratorPrototype%.next requires that |this| be an Array Iterator instance");

return next.@call(this);
}

0 comments on commit 83cc606

Please sign in to comment.