Diff
Modified: trunk/Source/_javascript_Core/CMakeLists.txt (253334 => 253335)
--- trunk/Source/_javascript_Core/CMakeLists.txt 2019-12-10 19:38:42 UTC (rev 253334)
+++ trunk/Source/_javascript_Core/CMakeLists.txt 2019-12-10 19:41:40 UTC (rev 253335)
@@ -214,10 +214,10 @@
)
add_custom_command(
- OUTPUT ${_javascript_Core_DERIVED_SOURCES_DIR}/Bytecodes.h ${_javascript_Core_DERIVED_SOURCES_DIR}/InitBytecodes.asm ${_javascript_Core_DERIVED_SOURCES_DIR}/BytecodeStructs.h ${_javascript_Core_DERIVED_SOURCES_DIR}/BytecodeIndices.h ${_javascript_Core_DERIVED_SOURCES_DIR}/WasmLLIntGeneratorInlines.h ${_javascript_Core_DERIVED_SOURCES_DIR}/InitWasm.asm
+ OUTPUT ${_javascript_Core_DERIVED_SOURCES_DIR}/Bytecodes.h ${_javascript_Core_DERIVED_SOURCES_DIR}/InitBytecodes.asm ${_javascript_Core_DERIVED_SOURCES_DIR}/BytecodeStructs.h ${_javascript_Core_DERIVED_SOURCES_DIR}/BytecodeIndices.h ${_javascript_Core_DERIVED_SOURCES_DIR}/WasmLLIntGeneratorInlines.h ${_javascript_Core_DERIVED_SOURCES_DIR}/InitWasm.asm ${_javascript_Core_DERIVED_SOURCES_DIR}/BytecodeDumperGenerated.cpp
MAIN_DEPENDENCY ${_javascript_CORE_DIR}/generator/main.rb
DEPENDS ${GENERATOR} bytecode/BytecodeList.rb
- COMMAND ${RUBY_EXECUTABLE} ${_javascript_CORE_DIR}/generator/main.rb --bytecodes_h ${_javascript_Core_DERIVED_SOURCES_DIR}/Bytecodes.h --init_bytecodes_asm ${_javascript_Core_DERIVED_SOURCES_DIR}/InitBytecodes.asm --bytecode_structs_h ${_javascript_Core_DERIVED_SOURCES_DIR}/BytecodeStructs.h --bytecode_indices_h ${_javascript_Core_DERIVED_SOURCES_DIR}/BytecodeIndices.h ${_javascript_CORE_DIR}/bytecode/BytecodeList.rb --wasm_json ${_javascript_CORE_DIR}/wasm/wasm.json --wasm_llint_generator_h ${_javascript_Core_DERIVED_SOURCES_DIR}/WasmLLIntGeneratorInlines.h --init_wasm_llint ${_javascript_Core_DERIVED_SOURCES_DIR}/InitWasm.asm
+ COMMAND ${RUBY_EXECUTABLE} ${_javascript_CORE_DIR}/generator/main.rb --bytecodes_h ${_javascript_Core_DERIVED_SOURCES_DIR}/Bytecodes.h --init_bytecodes_asm ${_javascript_Core_DERIVED_SOURCES_DIR}/InitBytecodes.asm --bytecode_structs_h ${_javascript_Core_DERIVED_SOURCES_DIR}/BytecodeStructs.h --bytecode_indices_h ${_javascript_Core_DERIVED_SOURCES_DIR}/BytecodeIndices.h ${_javascript_CORE_DIR}/bytecode/BytecodeList.rb --wasm_json ${_javascript_CORE_DIR}/wasm/wasm.json --wasm_llint_generator_h ${_javascript_Core_DERIVED_SOURCES_DIR}/WasmLLIntGeneratorInlines.h --init_wasm_llint ${_javascript_Core_DERIVED_SOURCES_DIR}/InitWasm.asm --bytecode_dumper ${_javascript_Core_DERIVED_SOURCES_DIR}/BytecodeDumperGenerated.cpp
VERBATIM)
Modified: trunk/Source/_javascript_Core/ChangeLog (253334 => 253335)
--- trunk/Source/_javascript_Core/ChangeLog 2019-12-10 19:38:42 UTC (rev 253334)
+++ trunk/Source/_javascript_Core/ChangeLog 2019-12-10 19:41:40 UTC (rev 253335)
@@ -1,3 +1,53 @@
+2019-12-10 Tadeu Zagallo <tzaga...@apple.com>
+
+ Reduce JSC's binary size
+ https://bugs.webkit.org/show_bug.cgi?id=204549
+
+ Reviewed by Saam Barati.
+
+ The Wasm interpreter landed in r251886 and significantly increased JSC's binary size. To try and
+ offset that, here and some easy fixes that get us ~200kb back:
+ - We were generating 2 instances of dumpBytecode, at 30kb each. I changed the generator to emit a cpp
+ file instead, avoiding the duplication.
+ - We had 3 instances of computeUsesForBytecodeIndex at 11kb each. I kept the work that depended on the
+ template type in the template function and moved the massive switch into computeUsesForBytecodeIndexImpl.
+ I also did the same for computeDefsForBytecodeIndex.
+ - We had 8 instances of emit_compareAndJump(Slow) at 8kb (7kb for Slow) each. I kept the code
+ that extracts the data from the bytecode in the template, but moved the bulk of the function
+ into emit_compareAndJump(Slow)Impl.
+
+ * CMakeLists.txt:
+ * DerivedSources-output.xcfilelist:
+ * DerivedSources.make:
+ * Sources.txt:
+ * bytecode/BytecodeDumper.cpp:
+ (JSC::BytecodeDumperBase::printLocationAndOp):
+ (JSC::BytecodeDumperBase::dumpValue):
+ * bytecode/BytecodeDumper.h:
+ (JSC::BytecodeDumperBase::~BytecodeDumperBase):
+ (JSC::BytecodeDumperBase::dumpValue):
+ (JSC::BytecodeDumperBase::BytecodeDumperBase):
+ (JSC::BytecodeDumper::BytecodeDumper):
+ * bytecode/BytecodeUseDef.cpp: Copied from Source/_javascript_Core/bytecode/BytecodeUseDef.h.
+ (JSC::computeUsesForBytecodeIndexImpl):
+ (JSC::computeDefsForBytecodeIndexImpl):
+ * bytecode/BytecodeUseDef.h:
+ (JSC::computeUsesForBytecodeIndex):
+ (JSC::computeDefsForBytecodeIndex):
+ * generator/DSL.rb:
+ * generator/Opcode.rb:
+ * generator/Options.rb:
+ * jit/JIT.h:
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::emit_compareAndJump):
+ (JSC::JIT::emit_compareAndJumpImpl):
+ (JSC::JIT::emit_compareUnsignedAndJump):
+ (JSC::JIT::emit_compareUnsignedAndJumpImpl):
+ (JSC::JIT::emit_compareUnsigned):
+ (JSC::JIT::emit_compareUnsignedImpl):
+ (JSC::JIT::emit_compareAndJumpSlow):
+ (JSC::JIT::emit_compareAndJumpSlowImpl):
+
2019-12-10 Yusuke Suzuki <ysuz...@apple.com>
[JSC] Put JSArray in IsoSubspace
Modified: trunk/Source/_javascript_Core/DerivedSources-output.xcfilelist (253334 => 253335)
--- trunk/Source/_javascript_Core/DerivedSources-output.xcfilelist 2019-12-10 19:38:42 UTC (rev 253334)
+++ trunk/Source/_javascript_Core/DerivedSources-output.xcfilelist 2019-12-10 19:41:40 UTC (rev 253335)
@@ -8,6 +8,7 @@
$(BUILT_PRODUCTS_DIR)/DerivedSources/_javascript_Core/BigIntConstructor.lut.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/_javascript_Core/BigIntPrototype.lut.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/_javascript_Core/BooleanPrototype.lut.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/_javascript_Core/BytecodeDumperGenerated.cpp
$(BUILT_PRODUCTS_DIR)/DerivedSources/_javascript_Core/BytecodeIndices.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/_javascript_Core/BytecodeStructs.h
$(BUILT_PRODUCTS_DIR)/DerivedSources/_javascript_Core/Bytecodes.h
Modified: trunk/Source/_javascript_Core/DerivedSources.make (253334 => 253335)
--- trunk/Source/_javascript_Core/DerivedSources.make 2019-12-10 19:38:42 UTC (rev 253334)
+++ trunk/Source/_javascript_Core/DerivedSources.make 2019-12-10 19:41:40 UTC (rev 253335)
@@ -218,6 +218,7 @@
InitBytecodes.asm \
WasmLLIntGeneratorInlines.h \
InitWasm.asm \
+ BytecodeDumperGenerated.cpp \
#
BYTECODE_FILES_PATTERNS = $(subst .,%,$(BYTECODE_FILES))
@@ -232,6 +233,7 @@
--wasm_json $(_javascript_Core)/wasm/wasm.json \
--wasm_llint_generator_h WasmLLIntGeneratorInlines.h \
--init_wasm_llint InitWasm.asm \
+ --bytecode_dumper BytecodeDumperGenerated.cpp \
# Inspector interfaces
Modified: trunk/Source/_javascript_Core/Sources.txt (253334 => 253335)
--- trunk/Source/_javascript_Core/Sources.txt 2019-12-10 19:38:42 UTC (rev 253334)
+++ trunk/Source/_javascript_Core/Sources.txt 2019-12-10 19:41:40 UTC (rev 253335)
@@ -201,6 +201,7 @@
bytecode/BytecodeIntrinsicRegistry.cpp
bytecode/BytecodeLivenessAnalysis.cpp
bytecode/BytecodeRewriter.cpp
+bytecode/BytecodeUseDef.cpp
bytecode/CallEdge.cpp
bytecode/CallLinkInfo.cpp
bytecode/CallLinkStatus.cpp
@@ -284,6 +285,9 @@
bytecode/VirtualRegister.cpp
bytecode/Watchpoint.cpp
+// Derived Sources
+BytecodeDumperGenerated.cpp
+
bytecompiler/BytecodeGenerator.cpp
bytecompiler/NodesCodegen.cpp
bytecompiler/ProfileTypeBytecodeFlag.cpp
Modified: trunk/Source/_javascript_Core/bytecode/BytecodeDumper.cpp (253334 => 253335)
--- trunk/Source/_javascript_Core/bytecode/BytecodeDumper.cpp 2019-12-10 19:38:42 UTC (rev 253334)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeDumper.cpp 2019-12-10 19:41:40 UTC (rev 253335)
@@ -55,6 +55,30 @@
return index >= FirstConstantRegisterIndex;
}
+void BytecodeDumperBase::printLocationAndOp(InstructionStream::Offset location, const char* op)
+{
+ m_currentLocation = location;
+ m_out.printf("[%4u] %-18s ", location, op);
+}
+
+void BytecodeDumperBase::dumpValue(VirtualRegister reg)
+{
+ m_out.printf("%s", registerName(reg.offset()).data());
+}
+
+template<typename Traits>
+void BytecodeDumperBase::dumpValue(GenericBoundLabel<Traits> label)
+{
+ InstructionStream::Offset targetOffset = label.target() + m_currentLocation;
+ m_out.print(label.target(), "(->", targetOffset, ")");
+}
+
+template void BytecodeDumperBase::dumpValue(GenericBoundLabel<JSGeneratorTraits>);
+
+#if ENABLE(WEBASSEMBLY)
+template void BytecodeDumperBase::dumpValue(GenericBoundLabel<Wasm::GeneratorTraits>);
+#endif // ENABLE(WEBASSEMBLY)
+
template<class Block>
CString BytecodeDumper<Block>::registerName(int r) const
{
@@ -72,19 +96,6 @@
}
template<class Block>
-void BytecodeDumper<Block>::printLocationAndOp(InstructionStream::Offset location, const char* op)
-{
- m_currentLocation = location;
- m_out.printf("[%4u] %-18s ", location, op);
-}
-
-template<class Block>
-void BytecodeDumper<Block>::dumpValue(VirtualRegister reg)
-{
- m_out.printf("%s", registerName(reg.offset()).data());
-}
-
-template<class Block>
void BytecodeDumper<Block>::dumpBytecode(const InstructionStream::Ref& it, const ICStatusMap&)
{
::JSC::dumpBytecode(this, it.offset(), it.ptr());
Modified: trunk/Source/_javascript_Core/bytecode/BytecodeDumper.h (253334 => 253335)
--- trunk/Source/_javascript_Core/bytecode/BytecodeDumper.h 2019-12-10 19:38:42 UTC (rev 253334)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeDumper.h 2019-12-10 19:41:40 UTC (rev 253335)
@@ -26,10 +26,10 @@
#pragma once
+#include "BytecodeGeneratorBase.h"
#include "CallLinkInfo.h"
#include "ICStatusMap.h"
#include "InstructionStream.h"
-#include "Label.h"
#include "StructureStubInfo.h"
namespace JSC {
@@ -36,10 +36,11 @@
struct Instruction;
-template<class Block>
-class BytecodeDumper {
+class BytecodeDumperBase {
public:
- static void dumpBytecode(Block*, PrintStream& out, const InstructionStream::Ref& it, const ICStatusMap& = ICStatusMap());
+ virtual ~BytecodeDumperBase()
+ {
+ }
void printLocationAndOp(InstructionStream::Offset location, const char* op);
@@ -54,18 +55,30 @@
void dumpValue(VirtualRegister);
template<typename Traits>
- void dumpValue(GenericBoundLabel<Traits> label)
+ void dumpValue(GenericBoundLabel<Traits>);
+
+ template<typename T>
+ void dumpValue(T v) { m_out.print(v); }
+
+protected:
+ virtual CString registerName(int) const = 0;
+
+ BytecodeDumperBase(PrintStream& out)
+ : m_out(out)
{
- InstructionStream::Offset targetOffset = label.target() + m_currentLocation;
- m_out.print(label.target(), "(->", targetOffset, ")");
}
+ PrintStream& m_out;
+ InstructionStream::Offset m_currentLocation { 0 };
+};
- template<typename T>
- void dumpValue(T v) { m_out.print(v); }
+template<class Block>
+class BytecodeDumper : public BytecodeDumperBase {
+public:
+ static void dumpBytecode(Block*, PrintStream& out, const InstructionStream::Ref& it, const ICStatusMap& = ICStatusMap());
BytecodeDumper(Block* block, PrintStream& out)
- : m_out(out)
+ : BytecodeDumperBase(out)
, m_block(block)
{
}
@@ -77,14 +90,12 @@
void dumpBytecode(const InstructionStream::Ref& it, const ICStatusMap&);
- PrintStream& m_out;
+ CString registerName(int r) const override;
private:
- CString registerName(int r) const;
virtual CString constantName(int index) const;
Block* m_block;
- InstructionStream::Offset m_currentLocation { 0 };
};
template<class Block>
Copied: trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.cpp (from rev 253334, trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.h) (0 => 253335)
--- trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.cpp (rev 0)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.cpp 2019-12-10 19:41:40 UTC (rev 253335)
@@ -0,0 +1,497 @@
+/*
+ * Copyright (C) 2013-2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "BytecodeUseDef.h"
+
+namespace JSC {
+
+#define CALL_FUNCTOR(__arg) \
+ functor(__bytecode.m_##__arg);
+
+#define USES_OR_DEFS(__opcode, ...) \
+ case __opcode::opcodeID: { \
+ auto __bytecode = instruction->as<__opcode>(); \
+ WTF_LAZY_FOR_EACH_TERM(CALL_FUNCTOR, __VA_ARGS__) \
+ return; \
+ }
+
+#define USES USES_OR_DEFS
+#define DEFS USES_OR_DEFS
+
+void computeUsesForBytecodeIndexImpl(VirtualRegister scopeRegister, const Instruction* instruction, const Function<void(VirtualRegister)>& functor)
+{
+ OpcodeID opcodeID = instruction->opcodeID();
+
+ auto handleNewArrayLike = [&](auto op) {
+ int base = op.m_argv.offset();
+ for (int i = 0; i < static_cast<int>(op.m_argc); i++)
+ functor(VirtualRegister { base - i });
+ };
+
+ auto handleOpCallLike = [&](auto op) {
+ functor(op.m_callee);
+ int lastArg = -static_cast<int>(op.m_argv) + CallFrame::thisArgumentOffset();
+ for (int i = 0; i < static_cast<int>(op.m_argc); i++)
+ functor(VirtualRegister { lastArg + i });
+ if (opcodeID == op_call_eval)
+ functor(scopeRegister);
+ return;
+ };
+
+ switch (opcodeID) {
+ case op_wide16:
+ case op_wide32:
+ RELEASE_ASSERT_NOT_REACHED();
+
+ // No uses.
+ case op_new_regexp:
+ case op_debug:
+ case op_jneq_ptr:
+ case op_loop_hint:
+ case op_jmp:
+ case op_new_object:
+ case op_new_promise:
+ case op_new_generator:
+ case op_enter:
+ case op_argument_count:
+ case op_catch:
+ case op_profile_control_flow:
+ case op_create_direct_arguments:
+ case op_create_cloned_arguments:
+ case op_get_rest_length:
+ case op_check_traps:
+ case op_get_argument:
+ case op_nop:
+ case op_unreachable:
+ case op_super_sampler_begin:
+ case op_super_sampler_end:
+ return;
+
+ USES(OpGetScope, dst)
+ USES(OpToThis, srcDst)
+ USES(OpCheckTdz, targetVirtualRegister)
+ USES(OpIdentityWithProfile, srcDst)
+ USES(OpProfileType, targetVirtualRegister);
+ USES(OpThrow, value)
+ USES(OpThrowStaticError, message)
+ USES(OpEnd, value)
+ USES(OpRet, value)
+ USES(OpJtrue, condition)
+ USES(OpJfalse, condition)
+ USES(OpJeqNull, value)
+ USES(OpJneqNull, value)
+ USES(OpJundefinedOrNull, value)
+ USES(OpJnundefinedOrNull, value)
+ USES(OpDec, srcDst)
+ USES(OpInc, srcDst)
+ USES(OpLogShadowChickenPrologue, scope)
+
+ USES(OpJless, lhs, rhs)
+ USES(OpJlesseq, lhs, rhs)
+ USES(OpJgreater, lhs, rhs)
+ USES(OpJgreatereq, lhs, rhs)
+ USES(OpJnless, lhs, rhs)
+ USES(OpJnlesseq, lhs, rhs)
+ USES(OpJngreater, lhs, rhs)
+ USES(OpJngreatereq, lhs, rhs)
+ USES(OpJeq, lhs, rhs)
+ USES(OpJneq, lhs, rhs)
+ USES(OpJstricteq, lhs, rhs)
+ USES(OpJnstricteq, lhs, rhs)
+ USES(OpJbelow, lhs, rhs)
+ USES(OpJbeloweq, lhs, rhs)
+ USES(OpSetFunctionName, function, name)
+ USES(OpLogShadowChickenTail, thisValue, scope)
+
+ USES(OpPutByVal, base, property, value)
+ USES(OpPutByValDirect, base, property, value)
+
+ USES(OpPutById, base, value)
+ USES(OpPutToScope, scope, value)
+ USES(OpPutToArguments, arguments, value)
+
+ USES(OpPutByIdWithThis, base, thisValue, value)
+
+ USES(OpPutByValWithThis, base, thisValue, property, value)
+
+ USES(OpPutGetterById, base, accessor)
+ USES(OpPutSetterById, base, accessor)
+
+ USES(OpPutGetterSetterById, base, getter, setter)
+
+ USES(OpPutGetterByVal, base, property, accessor)
+ USES(OpPutSetterByVal, base, property, accessor)
+
+ USES(OpDefineDataProperty, base, property, value, attributes)
+
+ USES(OpDefineAccessorProperty, base, property, getter, setter, attributes)
+
+ USES(OpSpread, argument)
+ USES(OpGetPropertyEnumerator, base)
+ USES(OpGetEnumerableLength, base)
+ USES(OpNewFuncExp, scope)
+ USES(OpNewGeneratorFuncExp, scope)
+ USES(OpNewAsyncFuncExp, scope)
+ USES(OpToIndexString, index)
+ USES(OpCreateLexicalEnvironment, scope, symbolTable, initialValue)
+ USES(OpCreateGeneratorFrameEnvironment, scope, symbolTable, initialValue)
+ USES(OpResolveScope, scope)
+ USES(OpResolveScopeForHoistingFuncDeclInEval, scope)
+ USES(OpGetFromScope, scope)
+ USES(OpToPrimitive, src)
+ USES(OpTryGetById, base)
+ USES(OpGetById, base)
+ USES(OpGetByIdDirect, base)
+ USES(OpInById, base)
+ USES(OpTypeof, value)
+ USES(OpIsEmpty, operand)
+ USES(OpIsUndefined, operand)
+ USES(OpIsUndefinedOrNull, operand)
+ USES(OpIsBoolean, operand)
+ USES(OpIsNumber, operand)
+ USES(OpIsObject, operand)
+ USES(OpIsObjectOrNull, operand)
+ USES(OpIsCellWithType, operand)
+ USES(OpIsFunction, operand)
+ USES(OpToNumber, operand)
+ USES(OpToNumeric, operand)
+ USES(OpToString, operand)
+ USES(OpToObject, operand)
+ USES(OpNegate, operand)
+ USES(OpBitnot, operand)
+ USES(OpEqNull, operand)
+ USES(OpNeqNull, operand)
+ USES(OpNot, operand)
+ USES(OpUnsigned, operand)
+ USES(OpMov, src)
+ USES(OpNewArrayWithSize, length)
+ USES(OpCreateThis, callee)
+ USES(OpCreatePromise, callee)
+ USES(OpCreateGenerator, callee)
+ USES(OpCreateAsyncGenerator, callee)
+ USES(OpDelById, base)
+ USES(OpNewFunc, scope)
+ USES(OpNewAsyncGeneratorFunc, scope)
+ USES(OpNewAsyncGeneratorFuncExp, scope)
+ USES(OpNewGeneratorFunc, scope)
+ USES(OpNewAsyncFunc, scope)
+ USES(OpGetParentScope, scope)
+ USES(OpCreateScopedArguments, scope)
+ USES(OpCreateRest, arraySize)
+ USES(OpGetFromArguments, arguments)
+ USES(OpNewArrayBuffer, immutableButterfly)
+
+ USES(OpHasGenericProperty, base, property)
+ USES(OpHasIndexedProperty, base, property)
+ USES(OpEnumeratorStructurePname, enumerator, index)
+ USES(OpEnumeratorGenericPname, enumerator, index)
+ USES(OpGetByVal, base, property)
+ USES(OpInByVal, base, property)
+ USES(OpOverridesHasInstance, constructor, hasInstanceValue)
+ USES(OpInstanceof, value, prototype)
+ USES(OpAdd, lhs, rhs)
+ USES(OpMul, lhs, rhs)
+ USES(OpDiv, lhs, rhs)
+ USES(OpMod, lhs, rhs)
+ USES(OpSub, lhs, rhs)
+ USES(OpPow, lhs, rhs)
+ USES(OpLshift, lhs, rhs)
+ USES(OpRshift, lhs, rhs)
+ USES(OpUrshift, lhs, rhs)
+ USES(OpBitand, lhs, rhs)
+ USES(OpBitxor, lhs, rhs)
+ USES(OpBitor, lhs, rhs)
+ USES(OpLess, lhs, rhs)
+ USES(OpLesseq, lhs, rhs)
+ USES(OpGreater, lhs, rhs)
+ USES(OpGreatereq, lhs, rhs)
+ USES(OpBelow, lhs, rhs)
+ USES(OpBeloweq, lhs, rhs)
+ USES(OpNstricteq, lhs, rhs)
+ USES(OpStricteq, lhs, rhs)
+ USES(OpNeq, lhs, rhs)
+ USES(OpEq, lhs, rhs)
+ USES(OpPushWithScope, currentScope, newScope)
+ USES(OpGetByIdWithThis, base, thisValue)
+ USES(OpDelByVal, base, property)
+ USES(OpTailCallForwardArguments, callee, thisValue)
+
+ USES(OpGetByValWithThis, base, thisValue, property)
+ USES(OpInstanceofCustom, value, constructor, hasInstanceValue)
+ USES(OpHasStructureProperty, base, property, enumerator)
+ USES(OpConstructVarargs, callee, thisValue, arguments)
+ USES(OpCallVarargs, callee, thisValue, arguments)
+ USES(OpTailCallVarargs, callee, thisValue, arguments)
+
+ USES(OpGetDirectPname, base, property, index, enumerator)
+
+ USES(OpSwitchString, scrutinee)
+ USES(OpSwitchChar, scrutinee)
+ USES(OpSwitchImm, scrutinee)
+
+ USES(OpGetInternalField, base)
+ USES(OpPutInternalField, base, value)
+
+ USES(OpYield, generator, argument)
+
+ case op_new_array_with_spread:
+ handleNewArrayLike(instruction->as<OpNewArrayWithSpread>());
+ return;
+ case op_new_array:
+ handleNewArrayLike(instruction->as<OpNewArray>());
+ return;
+
+ case op_strcat: {
+ auto bytecode = instruction->as<OpStrcat>();
+ int base = bytecode.m_src.offset();
+ for (int i = 0; i < bytecode.m_count; i++)
+ functor(VirtualRegister { base - i });
+ return;
+ }
+
+ case op_construct:
+ handleOpCallLike(instruction->as<OpConstruct>());
+ return;
+ case op_call_eval:
+ handleOpCallLike(instruction->as<OpCallEval>());
+ return;
+ case op_call:
+ handleOpCallLike(instruction->as<OpCall>());
+ return;
+ case op_tail_call:
+ handleOpCallLike(instruction->as<OpTailCall>());
+ return;
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+void computeDefsForBytecodeIndexImpl(unsigned numVars, const Instruction* instruction, const Function<void(VirtualRegister)>& functor)
+{
+ switch (instruction->opcodeID()) {
+ case op_wide16:
+ case op_wide32:
+ RELEASE_ASSERT_NOT_REACHED();
+
+ // These don't define anything.
+ case op_put_to_scope:
+ case op_end:
+ case op_throw:
+ case op_throw_static_error:
+ case op_check_tdz:
+ case op_debug:
+ case op_ret:
+ case op_jmp:
+ case op_jtrue:
+ case op_jfalse:
+ case op_jeq_null:
+ case op_jneq_null:
+ case op_jundefined_or_null:
+ case op_jnundefined_or_null:
+ case op_jneq_ptr:
+ case op_jless:
+ case op_jlesseq:
+ case op_jgreater:
+ case op_jgreatereq:
+ case op_jnless:
+ case op_jnlesseq:
+ case op_jngreater:
+ case op_jngreatereq:
+ case op_jeq:
+ case op_jneq:
+ case op_jstricteq:
+ case op_jnstricteq:
+ case op_jbelow:
+ case op_jbeloweq:
+ case op_loop_hint:
+ case op_switch_imm:
+ case op_switch_char:
+ case op_switch_string:
+ case op_put_by_id:
+ case op_put_by_id_with_this:
+ case op_put_by_val_with_this:
+ case op_put_getter_by_id:
+ case op_put_setter_by_id:
+ case op_put_getter_setter_by_id:
+ case op_put_getter_by_val:
+ case op_put_setter_by_val:
+ case op_put_by_val:
+ case op_put_by_val_direct:
+ case op_put_internal_field:
+ case op_define_data_property:
+ case op_define_accessor_property:
+ case op_profile_type:
+ case op_profile_control_flow:
+ case op_put_to_arguments:
+ case op_set_function_name:
+ case op_check_traps:
+ case op_log_shadow_chicken_prologue:
+ case op_log_shadow_chicken_tail:
+ case op_yield:
+ case op_nop:
+ case op_unreachable:
+ case op_super_sampler_begin:
+ case op_super_sampler_end:
+#define LLINT_HELPER_OPCODES(opcode, length) case opcode:
+ FOR_EACH_LLINT_OPCODE_EXTENSION(LLINT_HELPER_OPCODES);
+#undef LLINT_HELPER_OPCODES
+ return;
+ // These all have a single destination for the first argument.
+ DEFS(OpArgumentCount, dst)
+ DEFS(OpToIndexString, dst)
+ DEFS(OpGetEnumerableLength, dst)
+ DEFS(OpHasIndexedProperty, dst)
+ DEFS(OpHasStructureProperty, dst)
+ DEFS(OpHasGenericProperty, dst)
+ DEFS(OpGetDirectPname, dst)
+ DEFS(OpGetPropertyEnumerator, dst)
+ DEFS(OpEnumeratorStructurePname, dst)
+ DEFS(OpEnumeratorGenericPname, dst)
+ DEFS(OpGetParentScope, dst)
+ DEFS(OpPushWithScope, dst)
+ DEFS(OpCreateLexicalEnvironment, dst)
+ DEFS(OpCreateGeneratorFrameEnvironment, dst)
+ DEFS(OpResolveScope, dst)
+ DEFS(OpResolveScopeForHoistingFuncDeclInEval, dst)
+ DEFS(OpStrcat, dst)
+ DEFS(OpToPrimitive, dst)
+ DEFS(OpCreateThis, dst)
+ DEFS(OpCreatePromise, dst)
+ DEFS(OpCreateGenerator, dst)
+ DEFS(OpCreateAsyncGenerator, dst)
+ DEFS(OpNewArray, dst)
+ DEFS(OpNewArrayWithSpread, dst)
+ DEFS(OpSpread, dst)
+ DEFS(OpNewArrayBuffer, dst)
+ DEFS(OpNewArrayWithSize, dst)
+ DEFS(OpNewRegexp, dst)
+ DEFS(OpNewFunc, dst)
+ DEFS(OpNewFuncExp, dst)
+ DEFS(OpNewGeneratorFunc, dst)
+ DEFS(OpNewGeneratorFuncExp, dst)
+ DEFS(OpNewAsyncGeneratorFunc, dst)
+ DEFS(OpNewAsyncGeneratorFuncExp, dst)
+ DEFS(OpNewAsyncFunc, dst)
+ DEFS(OpNewAsyncFuncExp, dst)
+ DEFS(OpCallVarargs, dst)
+ DEFS(OpTailCallVarargs, dst)
+ DEFS(OpTailCallForwardArguments, dst)
+ DEFS(OpConstructVarargs, dst)
+ DEFS(OpGetFromScope, dst)
+ DEFS(OpCall, dst)
+ DEFS(OpTailCall, dst)
+ DEFS(OpCallEval, dst)
+ DEFS(OpConstruct, dst)
+ DEFS(OpTryGetById, dst)
+ DEFS(OpGetById, dst)
+ DEFS(OpGetByIdDirect, dst)
+ DEFS(OpGetByIdWithThis, dst)
+ DEFS(OpGetByValWithThis, dst)
+ DEFS(OpOverridesHasInstance, dst)
+ DEFS(OpInstanceof, dst)
+ DEFS(OpInstanceofCustom, dst)
+ DEFS(OpGetByVal, dst)
+ DEFS(OpTypeof, dst)
+ DEFS(OpIdentityWithProfile, srcDst)
+ DEFS(OpIsEmpty, dst)
+ DEFS(OpIsUndefined, dst)
+ USES(OpIsUndefinedOrNull, dst)
+ DEFS(OpIsBoolean, dst)
+ DEFS(OpIsNumber, dst)
+ DEFS(OpIsObject, dst)
+ DEFS(OpIsObjectOrNull, dst)
+ DEFS(OpIsCellWithType, dst)
+ DEFS(OpIsFunction, dst)
+ DEFS(OpInById, dst)
+ DEFS(OpInByVal, dst)
+ DEFS(OpToNumber, dst)
+ DEFS(OpToNumeric, dst)
+ DEFS(OpToString, dst)
+ DEFS(OpToObject, dst)
+ DEFS(OpNegate, dst)
+ DEFS(OpAdd, dst)
+ DEFS(OpMul, dst)
+ DEFS(OpDiv, dst)
+ DEFS(OpMod, dst)
+ DEFS(OpSub, dst)
+ DEFS(OpPow, dst)
+ DEFS(OpLshift, dst)
+ DEFS(OpRshift, dst)
+ DEFS(OpUrshift, dst)
+ DEFS(OpBitand, dst)
+ DEFS(OpBitxor, dst)
+ DEFS(OpBitor, dst)
+ DEFS(OpBitnot, dst)
+ DEFS(OpInc, srcDst)
+ DEFS(OpDec, srcDst)
+ DEFS(OpEq, dst)
+ DEFS(OpNeq, dst)
+ DEFS(OpStricteq, dst)
+ DEFS(OpNstricteq, dst)
+ DEFS(OpLess, dst)
+ DEFS(OpLesseq, dst)
+ DEFS(OpGreater, dst)
+ DEFS(OpGreatereq, dst)
+ DEFS(OpBelow, dst)
+ DEFS(OpBeloweq, dst)
+ DEFS(OpNeqNull, dst)
+ DEFS(OpEqNull, dst)
+ DEFS(OpNot, dst)
+ DEFS(OpMov, dst)
+ DEFS(OpNewObject, dst)
+ DEFS(OpNewPromise, dst)
+ DEFS(OpNewGenerator, dst)
+ DEFS(OpToThis, srcDst)
+ DEFS(OpGetScope, dst)
+ DEFS(OpCreateDirectArguments, dst)
+ DEFS(OpCreateScopedArguments, dst)
+ DEFS(OpCreateClonedArguments, dst)
+ DEFS(OpDelById, dst)
+ DEFS(OpDelByVal, dst)
+ DEFS(OpUnsigned, dst)
+ DEFS(OpGetFromArguments, dst)
+ DEFS(OpGetArgument, dst)
+ DEFS(OpCreateRest, dst)
+ DEFS(OpGetRestLength, dst)
+ DEFS(OpGetInternalField, dst)
+
+ DEFS(OpCatch, exception, thrownValue)
+
+ case op_enter: {
+ for (unsigned i = numVars; i--;)
+ functor(virtualRegisterForLocal(i));
+ return;
+ }
+ }
+}
+
+#undef CALL_FUNCTOR
+#undef USES_OR_DEFS
+#undef USES
+#undef DEFS
+} // namespace JSC
Modified: trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.h (253334 => 253335)
--- trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.h 2019-12-10 19:38:42 UTC (rev 253334)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.h 2019-12-10 19:41:40 UTC (rev 253335)
@@ -32,470 +32,23 @@
namespace JSC {
-#define CALL_FUNCTOR(__arg) \
- functor(__bytecode.m_##__arg);
+void computeUsesForBytecodeIndexImpl(VirtualRegister, const Instruction*, const Function<void(VirtualRegister)>&);
+void computeDefsForBytecodeIndexImpl(unsigned, const Instruction*, const Function<void(VirtualRegister)>&);
-#define USES_OR_DEFS(__opcode, ...) \
- case __opcode::opcodeID: { \
- auto __bytecode = instruction->as<__opcode>(); \
- WTF_LAZY_FOR_EACH_TERM(CALL_FUNCTOR, __VA_ARGS__) \
- return; \
- }
-
-#define USES USES_OR_DEFS
-#define DEFS USES_OR_DEFS
-
-template<typename Block, typename Functor>
-void computeUsesForBytecodeIndex(Block* codeBlock, const Instruction* instruction, const Functor& functor)
+template<typename Block>
+void computeUsesForBytecodeIndex(Block* codeBlock, const Instruction* instruction, const Function<void(VirtualRegister)>& functor)
{
OpcodeID opcodeID = instruction->opcodeID();
if (opcodeID != op_enter && (codeBlock->wasCompiledWithDebuggingOpcodes() || codeBlock->usesEval()) && codeBlock->scopeRegister().isValid())
functor(codeBlock->scopeRegister());
- auto handleNewArrayLike = [&](auto op) {
- int base = op.m_argv.offset();
- for (int i = 0; i < static_cast<int>(op.m_argc); i++)
- functor(VirtualRegister { base - i });
- };
-
- auto handleOpCallLike = [&](auto op) {
- functor(op.m_callee);
- int lastArg = -static_cast<int>(op.m_argv) + CallFrame::thisArgumentOffset();
- for (int i = 0; i < static_cast<int>(op.m_argc); i++)
- functor(VirtualRegister { lastArg + i });
- if (opcodeID == op_call_eval)
- functor(codeBlock->scopeRegister());
- return;
- };
-
- switch (opcodeID) {
- case op_wide16:
- case op_wide32:
- RELEASE_ASSERT_NOT_REACHED();
-
- // No uses.
- case op_new_regexp:
- case op_debug:
- case op_jneq_ptr:
- case op_loop_hint:
- case op_jmp:
- case op_new_object:
- case op_new_promise:
- case op_new_generator:
- case op_enter:
- case op_argument_count:
- case op_catch:
- case op_profile_control_flow:
- case op_create_direct_arguments:
- case op_create_cloned_arguments:
- case op_get_rest_length:
- case op_check_traps:
- case op_get_argument:
- case op_nop:
- case op_unreachable:
- case op_super_sampler_begin:
- case op_super_sampler_end:
- return;
-
- USES(OpGetScope, dst)
- USES(OpToThis, srcDst)
- USES(OpCheckTdz, targetVirtualRegister)
- USES(OpIdentityWithProfile, srcDst)
- USES(OpProfileType, targetVirtualRegister);
- USES(OpThrow, value)
- USES(OpThrowStaticError, message)
- USES(OpEnd, value)
- USES(OpRet, value)
- USES(OpJtrue, condition)
- USES(OpJfalse, condition)
- USES(OpJeqNull, value)
- USES(OpJneqNull, value)
- USES(OpJundefinedOrNull, value)
- USES(OpJnundefinedOrNull, value)
- USES(OpDec, srcDst)
- USES(OpInc, srcDst)
- USES(OpLogShadowChickenPrologue, scope)
-
- USES(OpJless, lhs, rhs)
- USES(OpJlesseq, lhs, rhs)
- USES(OpJgreater, lhs, rhs)
- USES(OpJgreatereq, lhs, rhs)
- USES(OpJnless, lhs, rhs)
- USES(OpJnlesseq, lhs, rhs)
- USES(OpJngreater, lhs, rhs)
- USES(OpJngreatereq, lhs, rhs)
- USES(OpJeq, lhs, rhs)
- USES(OpJneq, lhs, rhs)
- USES(OpJstricteq, lhs, rhs)
- USES(OpJnstricteq, lhs, rhs)
- USES(OpJbelow, lhs, rhs)
- USES(OpJbeloweq, lhs, rhs)
- USES(OpSetFunctionName, function, name)
- USES(OpLogShadowChickenTail, thisValue, scope)
-
- USES(OpPutByVal, base, property, value)
- USES(OpPutByValDirect, base, property, value)
-
- USES(OpPutById, base, value)
- USES(OpPutToScope, scope, value)
- USES(OpPutToArguments, arguments, value)
-
- USES(OpPutByIdWithThis, base, thisValue, value)
-
- USES(OpPutByValWithThis, base, thisValue, property, value)
-
- USES(OpPutGetterById, base, accessor)
- USES(OpPutSetterById, base, accessor)
-
- USES(OpPutGetterSetterById, base, getter, setter)
-
- USES(OpPutGetterByVal, base, property, accessor)
- USES(OpPutSetterByVal, base, property, accessor)
-
- USES(OpDefineDataProperty, base, property, value, attributes)
-
- USES(OpDefineAccessorProperty, base, property, getter, setter, attributes)
-
- USES(OpSpread, argument)
- USES(OpGetPropertyEnumerator, base)
- USES(OpGetEnumerableLength, base)
- USES(OpNewFuncExp, scope)
- USES(OpNewGeneratorFuncExp, scope)
- USES(OpNewAsyncFuncExp, scope)
- USES(OpToIndexString, index)
- USES(OpCreateLexicalEnvironment, scope, symbolTable, initialValue)
- USES(OpCreateGeneratorFrameEnvironment, scope, symbolTable, initialValue)
- USES(OpResolveScope, scope)
- USES(OpResolveScopeForHoistingFuncDeclInEval, scope)
- USES(OpGetFromScope, scope)
- USES(OpToPrimitive, src)
- USES(OpTryGetById, base)
- USES(OpGetById, base)
- USES(OpGetByIdDirect, base)
- USES(OpInById, base)
- USES(OpTypeof, value)
- USES(OpIsEmpty, operand)
- USES(OpIsUndefined, operand)
- USES(OpIsUndefinedOrNull, operand)
- USES(OpIsBoolean, operand)
- USES(OpIsNumber, operand)
- USES(OpIsObject, operand)
- USES(OpIsObjectOrNull, operand)
- USES(OpIsCellWithType, operand)
- USES(OpIsFunction, operand)
- USES(OpToNumber, operand)
- USES(OpToNumeric, operand)
- USES(OpToString, operand)
- USES(OpToObject, operand)
- USES(OpNegate, operand)
- USES(OpBitnot, operand)
- USES(OpEqNull, operand)
- USES(OpNeqNull, operand)
- USES(OpNot, operand)
- USES(OpUnsigned, operand)
- USES(OpMov, src)
- USES(OpNewArrayWithSize, length)
- USES(OpCreateThis, callee)
- USES(OpCreatePromise, callee)
- USES(OpCreateGenerator, callee)
- USES(OpCreateAsyncGenerator, callee)
- USES(OpDelById, base)
- USES(OpNewFunc, scope)
- USES(OpNewAsyncGeneratorFunc, scope)
- USES(OpNewAsyncGeneratorFuncExp, scope)
- USES(OpNewGeneratorFunc, scope)
- USES(OpNewAsyncFunc, scope)
- USES(OpGetParentScope, scope)
- USES(OpCreateScopedArguments, scope)
- USES(OpCreateRest, arraySize)
- USES(OpGetFromArguments, arguments)
- USES(OpNewArrayBuffer, immutableButterfly)
-
- USES(OpHasGenericProperty, base, property)
- USES(OpHasIndexedProperty, base, property)
- USES(OpEnumeratorStructurePname, enumerator, index)
- USES(OpEnumeratorGenericPname, enumerator, index)
- USES(OpGetByVal, base, property)
- USES(OpInByVal, base, property)
- USES(OpOverridesHasInstance, constructor, hasInstanceValue)
- USES(OpInstanceof, value, prototype)
- USES(OpAdd, lhs, rhs)
- USES(OpMul, lhs, rhs)
- USES(OpDiv, lhs, rhs)
- USES(OpMod, lhs, rhs)
- USES(OpSub, lhs, rhs)
- USES(OpPow, lhs, rhs)
- USES(OpLshift, lhs, rhs)
- USES(OpRshift, lhs, rhs)
- USES(OpUrshift, lhs, rhs)
- USES(OpBitand, lhs, rhs)
- USES(OpBitxor, lhs, rhs)
- USES(OpBitor, lhs, rhs)
- USES(OpLess, lhs, rhs)
- USES(OpLesseq, lhs, rhs)
- USES(OpGreater, lhs, rhs)
- USES(OpGreatereq, lhs, rhs)
- USES(OpBelow, lhs, rhs)
- USES(OpBeloweq, lhs, rhs)
- USES(OpNstricteq, lhs, rhs)
- USES(OpStricteq, lhs, rhs)
- USES(OpNeq, lhs, rhs)
- USES(OpEq, lhs, rhs)
- USES(OpPushWithScope, currentScope, newScope)
- USES(OpGetByIdWithThis, base, thisValue)
- USES(OpDelByVal, base, property)
- USES(OpTailCallForwardArguments, callee, thisValue)
-
- USES(OpGetByValWithThis, base, thisValue, property)
- USES(OpInstanceofCustom, value, constructor, hasInstanceValue)
- USES(OpHasStructureProperty, base, property, enumerator)
- USES(OpConstructVarargs, callee, thisValue, arguments)
- USES(OpCallVarargs, callee, thisValue, arguments)
- USES(OpTailCallVarargs, callee, thisValue, arguments)
-
- USES(OpGetDirectPname, base, property, index, enumerator)
-
- USES(OpSwitchString, scrutinee)
- USES(OpSwitchChar, scrutinee)
- USES(OpSwitchImm, scrutinee)
-
- USES(OpGetInternalField, base)
- USES(OpPutInternalField, base, value)
-
- USES(OpYield, generator, argument)
-
- case op_new_array_with_spread:
- handleNewArrayLike(instruction->as<OpNewArrayWithSpread>());
- return;
- case op_new_array:
- handleNewArrayLike(instruction->as<OpNewArray>());
- return;
-
- case op_strcat: {
- auto bytecode = instruction->as<OpStrcat>();
- int base = bytecode.m_src.offset();
- for (int i = 0; i < bytecode.m_count; i++)
- functor(VirtualRegister { base - i });
- return;
- }
-
- case op_construct:
- handleOpCallLike(instruction->as<OpConstruct>());
- return;
- case op_call_eval:
- handleOpCallLike(instruction->as<OpCallEval>());
- return;
- case op_call:
- handleOpCallLike(instruction->as<OpCall>());
- return;
- case op_tail_call:
- handleOpCallLike(instruction->as<OpTailCall>());
- return;
-
- default:
- RELEASE_ASSERT_NOT_REACHED();
- break;
- }
+ computeUsesForBytecodeIndexImpl(codeBlock->scopeRegister(), instruction, functor);
}
-template<typename Block, typename Functor>
-void computeDefsForBytecodeIndex(Block* codeBlock, const Instruction* instruction, const Functor& functor)
+template<typename Block>
+void computeDefsForBytecodeIndex(Block* codeBlock, const Instruction* instruction, const Function<void(VirtualRegister)>& functor)
{
- switch (instruction->opcodeID()) {
- case op_wide16:
- case op_wide32:
- RELEASE_ASSERT_NOT_REACHED();
-
- // These don't define anything.
- case op_put_to_scope:
- case op_end:
- case op_throw:
- case op_throw_static_error:
- case op_check_tdz:
- case op_debug:
- case op_ret:
- case op_jmp:
- case op_jtrue:
- case op_jfalse:
- case op_jeq_null:
- case op_jneq_null:
- case op_jundefined_or_null:
- case op_jnundefined_or_null:
- case op_jneq_ptr:
- case op_jless:
- case op_jlesseq:
- case op_jgreater:
- case op_jgreatereq:
- case op_jnless:
- case op_jnlesseq:
- case op_jngreater:
- case op_jngreatereq:
- case op_jeq:
- case op_jneq:
- case op_jstricteq:
- case op_jnstricteq:
- case op_jbelow:
- case op_jbeloweq:
- case op_loop_hint:
- case op_switch_imm:
- case op_switch_char:
- case op_switch_string:
- case op_put_by_id:
- case op_put_by_id_with_this:
- case op_put_by_val_with_this:
- case op_put_getter_by_id:
- case op_put_setter_by_id:
- case op_put_getter_setter_by_id:
- case op_put_getter_by_val:
- case op_put_setter_by_val:
- case op_put_by_val:
- case op_put_by_val_direct:
- case op_put_internal_field:
- case op_define_data_property:
- case op_define_accessor_property:
- case op_profile_type:
- case op_profile_control_flow:
- case op_put_to_arguments:
- case op_set_function_name:
- case op_check_traps:
- case op_log_shadow_chicken_prologue:
- case op_log_shadow_chicken_tail:
- case op_yield:
- case op_nop:
- case op_unreachable:
- case op_super_sampler_begin:
- case op_super_sampler_end:
-#define LLINT_HELPER_OPCODES(opcode, length) case opcode:
- FOR_EACH_LLINT_OPCODE_EXTENSION(LLINT_HELPER_OPCODES);
-#undef LLINT_HELPER_OPCODES
- return;
- // These all have a single destination for the first argument.
- DEFS(OpArgumentCount, dst)
- DEFS(OpToIndexString, dst)
- DEFS(OpGetEnumerableLength, dst)
- DEFS(OpHasIndexedProperty, dst)
- DEFS(OpHasStructureProperty, dst)
- DEFS(OpHasGenericProperty, dst)
- DEFS(OpGetDirectPname, dst)
- DEFS(OpGetPropertyEnumerator, dst)
- DEFS(OpEnumeratorStructurePname, dst)
- DEFS(OpEnumeratorGenericPname, dst)
- DEFS(OpGetParentScope, dst)
- DEFS(OpPushWithScope, dst)
- DEFS(OpCreateLexicalEnvironment, dst)
- DEFS(OpCreateGeneratorFrameEnvironment, dst)
- DEFS(OpResolveScope, dst)
- DEFS(OpResolveScopeForHoistingFuncDeclInEval, dst)
- DEFS(OpStrcat, dst)
- DEFS(OpToPrimitive, dst)
- DEFS(OpCreateThis, dst)
- DEFS(OpCreatePromise, dst)
- DEFS(OpCreateGenerator, dst)
- DEFS(OpCreateAsyncGenerator, dst)
- DEFS(OpNewArray, dst)
- DEFS(OpNewArrayWithSpread, dst)
- DEFS(OpSpread, dst)
- DEFS(OpNewArrayBuffer, dst)
- DEFS(OpNewArrayWithSize, dst)
- DEFS(OpNewRegexp, dst)
- DEFS(OpNewFunc, dst)
- DEFS(OpNewFuncExp, dst)
- DEFS(OpNewGeneratorFunc, dst)
- DEFS(OpNewGeneratorFuncExp, dst)
- DEFS(OpNewAsyncGeneratorFunc, dst)
- DEFS(OpNewAsyncGeneratorFuncExp, dst)
- DEFS(OpNewAsyncFunc, dst)
- DEFS(OpNewAsyncFuncExp, dst)
- DEFS(OpCallVarargs, dst)
- DEFS(OpTailCallVarargs, dst)
- DEFS(OpTailCallForwardArguments, dst)
- DEFS(OpConstructVarargs, dst)
- DEFS(OpGetFromScope, dst)
- DEFS(OpCall, dst)
- DEFS(OpTailCall, dst)
- DEFS(OpCallEval, dst)
- DEFS(OpConstruct, dst)
- DEFS(OpTryGetById, dst)
- DEFS(OpGetById, dst)
- DEFS(OpGetByIdDirect, dst)
- DEFS(OpGetByIdWithThis, dst)
- DEFS(OpGetByValWithThis, dst)
- DEFS(OpOverridesHasInstance, dst)
- DEFS(OpInstanceof, dst)
- DEFS(OpInstanceofCustom, dst)
- DEFS(OpGetByVal, dst)
- DEFS(OpTypeof, dst)
- DEFS(OpIdentityWithProfile, srcDst)
- DEFS(OpIsEmpty, dst)
- DEFS(OpIsUndefined, dst)
- USES(OpIsUndefinedOrNull, dst)
- DEFS(OpIsBoolean, dst)
- DEFS(OpIsNumber, dst)
- DEFS(OpIsObject, dst)
- DEFS(OpIsObjectOrNull, dst)
- DEFS(OpIsCellWithType, dst)
- DEFS(OpIsFunction, dst)
- DEFS(OpInById, dst)
- DEFS(OpInByVal, dst)
- DEFS(OpToNumber, dst)
- DEFS(OpToNumeric, dst)
- DEFS(OpToString, dst)
- DEFS(OpToObject, dst)
- DEFS(OpNegate, dst)
- DEFS(OpAdd, dst)
- DEFS(OpMul, dst)
- DEFS(OpDiv, dst)
- DEFS(OpMod, dst)
- DEFS(OpSub, dst)
- DEFS(OpPow, dst)
- DEFS(OpLshift, dst)
- DEFS(OpRshift, dst)
- DEFS(OpUrshift, dst)
- DEFS(OpBitand, dst)
- DEFS(OpBitxor, dst)
- DEFS(OpBitor, dst)
- DEFS(OpBitnot, dst)
- DEFS(OpInc, srcDst)
- DEFS(OpDec, srcDst)
- DEFS(OpEq, dst)
- DEFS(OpNeq, dst)
- DEFS(OpStricteq, dst)
- DEFS(OpNstricteq, dst)
- DEFS(OpLess, dst)
- DEFS(OpLesseq, dst)
- DEFS(OpGreater, dst)
- DEFS(OpGreatereq, dst)
- DEFS(OpBelow, dst)
- DEFS(OpBeloweq, dst)
- DEFS(OpNeqNull, dst)
- DEFS(OpEqNull, dst)
- DEFS(OpNot, dst)
- DEFS(OpMov, dst)
- DEFS(OpNewObject, dst)
- DEFS(OpNewPromise, dst)
- DEFS(OpNewGenerator, dst)
- DEFS(OpToThis, srcDst)
- DEFS(OpGetScope, dst)
- DEFS(OpCreateDirectArguments, dst)
- DEFS(OpCreateScopedArguments, dst)
- DEFS(OpCreateClonedArguments, dst)
- DEFS(OpDelById, dst)
- DEFS(OpDelByVal, dst)
- DEFS(OpUnsigned, dst)
- DEFS(OpGetFromArguments, dst)
- DEFS(OpGetArgument, dst)
- DEFS(OpCreateRest, dst)
- DEFS(OpGetRestLength, dst)
- DEFS(OpGetInternalField, dst)
-
- DEFS(OpCatch, exception, thrownValue)
-
- case op_enter: {
- for (unsigned i = codeBlock->numVars(); i--;)
- functor(virtualRegisterForLocal(i));
- return;
- }
- }
+ computeDefsForBytecodeIndexImpl(codeBlock->numVars(), instruction, functor);
}
#undef CALL_FUNCTOR
Modified: trunk/Source/_javascript_Core/generator/DSL.rb (253334 => 253335)
--- trunk/Source/_javascript_Core/generator/DSL.rb 2019-12-10 19:38:42 UTC (rev 253334)
+++ trunk/Source/_javascript_Core/generator/DSL.rb 2019-12-10 19:41:40 UTC (rev 253335)
@@ -108,6 +108,7 @@
write_bytecodes(bytecode_list, options[:bytecodes_filename])
write_bytecode_structs(bytecode_list, options[:bytecode_structs_filename])
+ write_bytecode_dumper(bytecode_list, options[:bytecode_dumper_filename])
write_bytecodes_init(options[:init_asm_filename], bytecode_list)
write_indices(bytecode_list, options[:bytecode_indices_filename])
write_llint_generator(options[:wasm_llint_generator_filename], bytecode_list, @wasm_json)
@@ -127,8 +128,6 @@
def self.write_bytecode_structs(bytecode_list, bytecode_structs_filename)
GeneratedFile::create(bytecode_structs_filename, bytecode_list) do |template|
- opcodes = opcodes_for(:emit_in_structs_file)
-
template.prefix = <<-EOF
#pragma once
@@ -144,12 +143,43 @@
#include "ToThisStatus.h"
namespace JSC {
+
+void dumpBytecode(BytecodeDumperBase* dumper, InstructionStream::Offset, const Instruction*);
+
+#if ENABLE(WEBASSEMBLY)
+void dumpWasm(BytecodeDumperBase* dumper, InstructionStream::Offset, const Instruction*);
+#endif // ENABLE(WEBASSEMBLY)
+
EOF
template.body = <<-EOF
-#{opcodes.map(&:struct).join("\n")}
+#{opcodes_filter { |s| s.config[:emit_in_structs_file] && !s.is_wasm? }.map(&:struct).join("\n")}
+
+#if ENABLE(WEBASSEMBLY)
+#{opcodes_filter { |s| s.config[:emit_in_structs_file] && s.is_wasm? }.map(&:struct).join("\n")}
+#endif // ENABLE(WEBASSEMBLY)
+EOF
+ template.suffix = "} // namespace JSC"
+ end
+ end
+
+ def self.write_bytecode_dumper(bytecode_list, bytecode_dumper_filename)
+ GeneratedFile::create(bytecode_dumper_filename, bytecode_list) do |template|
+ template.prefix = <<-EOF
+#include "config.h"
+#include "BytecodeDumper.h"
+
+#include "BytecodeStructs.h"
+
+namespace JSC {
+EOF
+
+ template.body = <<-EOF
#{Opcode.dump_bytecode(:Bytecode, :JSOpcodeTraits, opcodes_filter { |s| s.config[:emit_in_structs_file] && !s.is_wasm? })}
+
+#if ENABLE(WEBASSEMBLY)
#{Opcode.dump_bytecode(:Wasm, :WasmOpcodeTraits, opcodes_filter { |s| s.is_wasm? })}
+#endif // ENABLE(WEBASSEMBLY)
EOF
template.suffix = "} // namespace JSC"
end
Modified: trunk/Source/_javascript_Core/generator/Opcode.rb (253334 => 253335)
--- trunk/Source/_javascript_Core/generator/Opcode.rb 2019-12-10 19:38:42 UTC (rev 253334)
+++ trunk/Source/_javascript_Core/generator/Opcode.rb 2019-12-10 19:41:40 UTC (rev 253335)
@@ -223,8 +223,7 @@
def dumper
<<-EOF
- template<typename Block>
- void dump(BytecodeDumper<Block>* dumper, InstructionStream::Offset __location, int __sizeShiftAmount)
+ void dump(BytecodeDumperBase* dumper, InstructionStream::Offset __location, int __sizeShiftAmount)
{
dumper->printLocationAndOp(__location, &"**#{@name}"[2 - __sizeShiftAmount]);
#{print_args { |arg|
@@ -326,8 +325,7 @@
def self.dump_bytecode(name, opcode_traits, opcodes)
<<-EOF.chomp
-template<typename BytecodeDumper>
-static void dump#{name}(BytecodeDumper* dumper, InstructionStream::Offset __location, const Instruction* __instruction)
+void dump#{name}(BytecodeDumperBase* dumper, InstructionStream::Offset __location, const Instruction* __instruction)
{
switch (__instruction->opcodeID<#{opcode_traits}>()) {
#{opcodes.map { |op|
Modified: trunk/Source/_javascript_Core/generator/Options.rb (253334 => 253335)
--- trunk/Source/_javascript_Core/generator/Options.rb 2019-12-10 19:38:42 UTC (rev 253334)
+++ trunk/Source/_javascript_Core/generator/Options.rb 2019-12-10 19:41:40 UTC (rev 253335)
@@ -56,6 +56,10 @@
long: "--init_wasm_llint FILE",
desc: "generate Wasm bytecodes init FILE",
},
+ bytecode_dumper_filename: {
+ long: "--bytecode_dumper FILE",
+ desc: "generate bytecode dumper FILE",
+ },
};
module Options
Modified: trunk/Source/_javascript_Core/jit/JIT.h (253334 => 253335)
--- trunk/Source/_javascript_Core/jit/JIT.h 2019-12-10 19:38:42 UTC (rev 253334)
+++ trunk/Source/_javascript_Core/jit/JIT.h 2019-12-10 19:41:40 UTC (rev 253335)
@@ -469,12 +469,16 @@
template<typename Op>
void emit_compareAndJump(const Instruction*, RelationalCondition);
+ void emit_compareAndJumpImpl(int op1, int op2, unsigned target, RelationalCondition);
template<typename Op>
void emit_compareUnsigned(const Instruction*, RelationalCondition);
+ void emit_compareUnsignedImpl(int dst, int op1, int op2, RelationalCondition);
template<typename Op>
void emit_compareUnsignedAndJump(const Instruction*, RelationalCondition);
+ void emit_compareUnsignedAndJumpImpl(int op1, int op2, unsigned target, RelationalCondition);
template<typename Op>
void emit_compareAndJumpSlow(const Instruction*, DoubleCondition, size_t (JIT_OPERATION *operation)(JSGlobalObject*, EncodedJSValue, EncodedJSValue), bool invert, Vector<SlowCaseEntry>::iterator&);
+ void emit_compareAndJumpSlowImpl(int op1, int op2, unsigned target, size_t instructionSize, DoubleCondition, size_t (JIT_OPERATION *operation)(JSGlobalObject*, EncodedJSValue, EncodedJSValue), bool invert, Vector<SlowCaseEntry>::iterator&);
void assertStackPointerOffset();
Modified: trunk/Source/_javascript_Core/jit/JITArithmetic.cpp (253334 => 253335)
--- trunk/Source/_javascript_Core/jit/JITArithmetic.cpp 2019-12-10 19:38:42 UTC (rev 253334)
+++ trunk/Source/_javascript_Core/jit/JITArithmetic.cpp 2019-12-10 19:41:40 UTC (rev 253335)
@@ -171,15 +171,20 @@
template<typename Op>
void JIT::emit_compareAndJump(const Instruction* instruction, RelationalCondition condition)
{
+ auto bytecode = instruction->as<Op>();
+ int op1 = bytecode.m_lhs.offset();
+ int op2 = bytecode.m_rhs.offset();
+ unsigned target = jumpTarget(instruction, bytecode.m_targetLabel);
+ emit_compareAndJumpImpl(op1, op2, target, condition);
+}
+
+void JIT::emit_compareAndJumpImpl(int op1, int op2, unsigned target, RelationalCondition condition)
+{
// We generate inline code for the following cases in the fast path:
// - int immediate to constant int immediate
// - constant int immediate to int immediate
// - int immediate to int immediate
- auto bytecode = instruction->as<Op>();
- int op1 = bytecode.m_lhs.offset();
- int op2 = bytecode.m_rhs.offset();
- unsigned target = jumpTarget(instruction, bytecode.m_targetLabel);
bool disallowAllocation = false;
if (isOperandConstantChar(op1)) {
emitGetVirtualRegister(op2, regT0);
@@ -228,6 +233,11 @@
int op1 = bytecode.m_lhs.offset();
int op2 = bytecode.m_rhs.offset();
unsigned target = jumpTarget(instruction, bytecode.m_targetLabel);
+ emit_compareUnsignedAndJumpImpl(op1, op2, target, condition);
+}
+
+void JIT::emit_compareUnsignedAndJumpImpl(int op1, int op2, unsigned target, RelationalCondition condition)
+{
if (isOperandConstantInt(op2)) {
emitGetVirtualRegister(op1, regT0);
int32_t op2imm = getOperandConstantInt(op2);
@@ -249,6 +259,11 @@
int dst = bytecode.m_dst.offset();
int op1 = bytecode.m_lhs.offset();
int op2 = bytecode.m_rhs.offset();
+ emit_compareUnsignedImpl(dst, op1, op2, condition);
+}
+
+void JIT::emit_compareUnsignedImpl(int dst, int op1, int op2, RelationalCondition condition)
+{
if (isOperandConstantInt(op2)) {
emitGetVirtualRegister(op1, regT0);
int32_t op2imm = getOperandConstantInt(op2);
@@ -272,7 +287,12 @@
int op1 = bytecode.m_lhs.offset();
int op2 = bytecode.m_rhs.offset();
unsigned target = jumpTarget(instruction, bytecode.m_targetLabel);
+ emit_compareAndJumpSlowImpl(op1, op2, target, instruction->size(), condition, operation, invert, iter);
+}
+void JIT::emit_compareAndJumpSlowImpl(int op1, int op2, unsigned target, size_t instructionSize, DoubleCondition condition, size_t (JIT_OPERATION *operation)(JSGlobalObject*, EncodedJSValue, EncodedJSValue), bool invert, Vector<SlowCaseEntry>::iterator& iter)
+{
+
// We generate inline code for the following cases in the slow path:
// - floating-point number to constant int immediate
// - constant int immediate to floating-point number
@@ -302,7 +322,7 @@
emitJumpSlowToHot(branchDouble(condition, fpRegT0, fpRegT1), target);
- emitJumpSlowToHot(jump(), instruction->size());
+ emitJumpSlowToHot(jump(), instructionSize);
fail1.link(this);
}
@@ -328,7 +348,7 @@
emitJumpSlowToHot(branchDouble(condition, fpRegT0, fpRegT1), target);
- emitJumpSlowToHot(jump(), instruction->size());
+ emitJumpSlowToHot(jump(), instructionSize);
fail1.link(this);
}
@@ -352,7 +372,7 @@
emitJumpSlowToHot(branchDouble(condition, fpRegT0, fpRegT1), target);
- emitJumpSlowToHot(jump(), instruction->size());
+ emitJumpSlowToHot(jump(), instructionSize);
fail1.link(this);
fail2.link(this);