[JSC] Make sharing of unlinked baseline code possible on JSVALUE32_64
https://bugs.webkit.org/show_bug.cgi?id=232624
Patch by Geza Lore <Geza Lore> on 2021-11-22
Reviewed by Yusuke Suzuki.
PerformanceTests/SunSpider:
Add extra SunSpider run on 32-bit platforms exerciseing baseline JIT
code sharing.
- with-baseline-code-sharing.yaml: Added.
Source/JavaScriptCore:
This patch contains a few different changes, which taken together make
it possible to share the unlinked baseline JIT code between different
CodeBlocks on JSVALUE32_64 platforms. Note that by default, code
sharing is disabled on JSVALUE32_64 due to the increased executable
memory usage it may cause. The reson the executable memory usage might
increase is that the UnlinkedCodeBlock has a longer lifetime than the
corresponding linked CodeBlocks (due to the CodeCache I'm told), and
when using code sharing, it holds a reference to the JITed code. This
then prevents recycling of executable memory while the
UnlinkedCodeBlock is live, while without sharing we could have
reclaimed some of the executable memory earlier.
The high level changes in this pach are:
- A lot of baseline implementations of the opcodes that needed
changing for the unlinked baseline are now unified between the
JSVALUE64 and JSVALUE32_64 platforms. Note that while this required
adding some abstraction, the code generated by the baseline JIT on
JSVALUE64 should be identical using this abstraction compared to
before.
- I added a JSRInfo class which defines standard names for certain
JSValueReg instances. This enables a lot of the unification in the
point above to be expressed in a very simple manner, with very little
transformation of the existing code. Again, this should have no impact
on the generated code on JSVALUE64, apart from some register
substitutions.
- The sizes of the resolve_scope and get_from_scope ops increased
significantly with the unlinked baseline. This can cause issues on
some JSVALUE32_64 targets where memory is more precious, so for these
two ops I swapped in the implementations under EXTRA_CTI_THUNKS, which
implement these using shared stubs. These stubs work on all platforms
that support ENABLE(JIT), so they are now the only implementation and
I have removed the basic bloated versions.
- Removed some unused code and fields I discovered while working on
this, strictly speaking this is not necessary for the functional
change.
- JavaScriptCore.xcodeproj/project.pbxproj:
- Sources.txt:
- jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::storeValue):
(JSC::AssemblyHelpers::isNull):
(JSC::AssemblyHelpers::isNotNull):
(JSC::AssemblyHelpers::emitTurnUndefinedIntoNull):
(JSC::AssemblyHelpers::noOverlap):
(JSC::AssemblyHelpers::noOverlapImpl):
(JSC::AssemblyHelpers::noOverlapImplRegMask):
- jit/GPRInfo.h:
- jit/JIT.cpp:
(JSC::JIT::privateCompileSlowCases):
(JSC::JIT::compileAndLinkWithoutFinalizing):
(JSC::JIT::link):
(JSC::JIT::privateCompileExceptionHandlers):
- jit/JIT.h:
- jit/JITArithmetic.cpp:
(JSC::JIT::emit_compareAndJumpImpl):
(JSC::JIT::emit_compareUnsignedAndJumpImpl):
(JSC::JIT::emit_compareUnsignedImpl):
(JSC::JIT::emit_op_mod):
(JSC::JIT::emit_compareAndJump):
(JSC::JIT::emit_compareUnsignedAndJump):
(JSC::JIT::emit_compareUnsigned):
(JSC::JIT::emit_compareAndJumpSlow):
(JSC::JIT::emitBinaryDoubleOp):
- jit/JITArithmetic32_64.cpp:
(JSC::JIT::emit_op_unsigned):
(JSC::JIT::emit_op_inc):
(JSC::JIT::emit_op_dec):
(JSC::JIT::emit_op_ret):
(JSC::JIT::compileSetupFrame):
(JSC::JIT::compileOpCall):
(JSC::JIT::emit_op_iterator_open):
(JSC::JIT::emit_op_iterator_next):
(JSC::JIT::getConstantOperand):
(JSC::JIT::appendCallWithExceptionCheckSetJSValueResult):
(JSC::JIT::appendCallWithExceptionCheckSetJSValueResultWithProfile):
(JSC::JIT::emitValueProfilingSiteIfProfiledOpcode):
(JSC::JIT::emitValueProfilingSite):
(JSC::JIT::emitGetVirtualRegister):
(JSC::JIT::emitPutVirtualRegister):
(JSC::JIT::emitGetVirtualRegisterPayload):
(JSC::JIT::emitGetVirtualRegisterTag):
(JSC::JIT::emitLoadDouble):
(JSC::loadAddrOfCodeBlockConstantBuffer):
(JSC::JIT::loadCodeBlockConstant):
(JSC::JIT::loadCodeBlockConstantPayload):
(JSC::JIT::loadCodeBlockConstantTag):
(JSC::JIT::emit_op_mov):
(JSC::JIT::emit_op_end):
(JSC::JIT::emit_op_new_object):
(JSC::JIT::emitSlow_op_new_object):
(JSC::JIT::emit_op_typeof_is_undefined):
(JSC::JIT::emit_op_is_undefined_or_null):
(JSC::JIT::emit_op_set_function_name):
(JSC::JIT::emit_op_jfalse):
(JSC::JIT::valueIsFalseyGenerator):
(JSC::JIT::emit_op_jeq_null):
(JSC::JIT::emit_op_jneq_null):
(JSC::JIT::emit_op_jeq_ptr):
(JSC::JIT::emit_op_jneq_ptr):
(JSC::JIT::emit_op_eq):
(JSC::JIT::emit_op_jeq):
(JSC::JIT::emit_op_jtrue):
(JSC::JIT::valueIsTruthyGenerator):
(JSC::JIT::emit_op_neq):
(JSC::JIT::emit_op_jneq):
(JSC::JIT::emit_op_throw):
(JSC::JIT::compileOpStrictEq):
(JSC::JIT::compileOpStrictEqJump):
(JSC::JIT::emit_op_switch_imm):
(JSC::JIT::emit_op_switch_char):
(JSC::JIT::emit_op_switch_string):
(JSC::JIT::emit_op_eq_null):
(JSC::JIT::emit_op_neq_null):
(JSC::JIT::emit_op_to_this):
(JSC::JIT::emit_op_create_this):
(JSC::JIT::emit_op_instanceof_custom):
(JSC::JIT::emitSlow_op_instanceof_custom):
(JSC::JIT::emit_op_loop_hint):
(JSC::JIT::emitNewFuncCommon):
(JSC::JIT::emitNewFuncExprCommon):
(JSC::JIT::emit_op_new_array_with_size):
(JSC::JIT::emit_op_profile_type):
(JSC::JIT::emit_op_log_shadow_chicken_prologue):
(JSC::JIT::emit_op_log_shadow_chicken_tail):
(JSC::JIT::emit_op_get_argument):
(JSC::JIT::emit_op_get_prototype_of):
(JSC::JIT::emit_op_overrides_has_instance):
(JSC::JIT::emit_op_instanceof):
(JSC::JIT::emitSlow_op_instanceof):
(JSC::JIT::emit_op_is_empty):
(JSC::JIT::emit_op_is_boolean):
(JSC::JIT::emit_op_is_number):
(JSC::JIT::emit_op_is_cell_with_type):
(JSC::JIT::emit_op_is_object):
(JSC::JIT::emit_op_to_primitive):
(JSC::JIT::emit_op_to_property_key):
(JSC::JIT::emit_op_not):
(JSC::JIT::emit_op_jundefined_or_null):
(JSC::JIT::emit_op_jnundefined_or_null):
(JSC::JIT::emit_op_jeq_ptr):
(JSC::JIT::emit_op_jneq_ptr):
(JSC::JIT::emit_op_eq):
(JSC::JIT::emitSlow_op_eq):
(JSC::JIT::emit_op_jeq):
(JSC::JIT::compileOpEqJumpSlow):
(JSC::JIT::emit_op_neq):
(JSC::JIT::emitSlow_op_neq):
(JSC::JIT::emit_op_jneq):
(JSC::JIT::compileOpStrictEq):
(JSC::JIT::compileOpStrictEqJump):
(JSC::JIT::emitSlow_op_jstricteq):
(JSC::JIT::emitSlow_op_jnstricteq):
(JSC::JIT::emit_op_to_number):
(JSC::JIT::emit_op_to_numeric):
(JSC::JIT::emit_op_to_string):
(JSC::JIT::emit_op_to_object):
(JSC::JIT::emit_op_get_parent_scope):
(JSC::JIT::emit_op_enter):
(JSC::JIT::emit_op_check_tdz):
- jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_put_getter_by_id):
(JSC::JIT::emit_op_put_setter_by_id):
(JSC::JIT::emit_op_put_getter_setter_by_id):
(JSC::JIT::emit_op_put_getter_by_val):
(JSC::JIT::emit_op_put_setter_by_val):
(JSC::JIT::emit_op_resolve_scope):
(JSC::JIT::generateOpResolveScopeThunk):
(JSC::JIT::slow_op_resolve_scopeGenerator):
(JSC::JIT::emit_op_get_from_scope):
(JSC::JIT::generateOpGetFromScopeThunk):
(JSC::JIT::slow_op_get_from_scopeGenerator):
(JSC::JIT::emit_op_put_to_scope):
(JSC::JIT::emit_op_get_from_arguments):
(JSC::JIT::emit_op_put_to_arguments):
(JSC::JIT::emit_op_get_internal_field):
(JSC::JIT::emit_op_put_internal_field):
(JSC::JIT::emit_op_get_property_enumerator):
(JSC::JIT::emit_op_enumerator_next):
(JSC::JIT::emit_op_enumerator_get_by_val):
(JSC::JIT::emitSlow_op_enumerator_get_by_val):
(JSC::JIT::emit_op_enumerator_in_by_val):
(JSC::JIT::emit_op_enumerator_has_own_property):
(JSC::JIT::emitWriteBarrier):
- jit/JITPropertyAccess32_64.cpp: Removed.
- jit/JSInterfaceJIT.h:
- jit/ThunkGenerators.cpp:
(JSC::popThunkStackPreservesAndHandleExceptionGenerator):
- jit/ThunkGenerators.h:
- runtime/OptionsList.h:
Tools:
Add extra SunSpider run on 32-bit platforms exerciseing baseline JIT
code sharing.
- Scripts/run-javascriptcore-tests:
(runJSCStressTests):