Apply poisoning to more pointers in JSC.
[WebKit-https.git] / Source / JavaScriptCore / llint / LowLevelInterpreter64.asm
index b30afa2..da4adb0 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2011-2016 Apple Inc. All rights reserved.
+# Copyright (C) 2011-2018 Apple Inc. All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
@@ -45,6 +45,7 @@ macro dispatchAfterCall()
     loadi ArgumentCount + TagOffset[cfr], PC
     loadp CodeBlock[cfr], PB
     loadp CodeBlock::m_instructions[PB], PB
+    unpoison(CodeBlockPoison, PB)
     loadisFromInstruction(1, t1)
     storeq r0, [cfr, t1, 8]
     valueProfile(r0, (CallOpCodeSize - 1), t3)
@@ -129,13 +130,14 @@ macro doVMEntry(makeCall)
     storep vm, VMEntryRecord::m_vm[sp]
     loadp VM::topCallFrame[vm], t4
     storep t4, VMEntryRecord::m_prevTopCallFrame[sp]
-    loadp VM::topVMEntryFrame[vm], t4
-    storep t4, VMEntryRecord::m_prevTopVMEntryFrame[sp]
+    loadp VM::topEntryFrame[vm], t4
+    storep t4, VMEntryRecord::m_prevTopEntryFrame[sp]
 
     loadi ProtoCallFrame::paddedArgCount[protoCallFrame], t4
     addp CallFrameHeaderSlots, t4, t4
     lshiftp 3, t4
     subp sp, t4, t3
+    bqbeq sp, t3, .throwStackOverflow
 
     # Ensure that we have enough additional stack capacity for the incoming args,
     # and the frame for the JS code we're executing. We need to do this check
@@ -160,6 +162,7 @@ macro doVMEntry(makeCall)
         move t5, vm
     end
 
+.throwStackOverflow:
     move vm, a0
     move protoCallFrame, a1
     cCall2(_llint_throw_stack_overflow_error)
@@ -169,8 +172,8 @@ macro doVMEntry(makeCall)
     loadp VMEntryRecord::m_vm[t4], vm
     loadp VMEntryRecord::m_prevTopCallFrame[t4], extraTempReg
     storep extraTempReg, VM::topCallFrame[vm]
-    loadp VMEntryRecord::m_prevTopVMEntryFrame[t4], extraTempReg
-    storep extraTempReg, VM::topVMEntryFrame[vm]
+    loadp VMEntryRecord::m_prevTopEntryFrame[t4], extraTempReg
+    storep extraTempReg, VM::topEntryFrame[vm]
 
     subp cfr, CalleeRegisterSaveSize, sp
 
@@ -183,6 +186,7 @@ macro doVMEntry(makeCall)
     move 4, t3
 
 .copyHeaderLoop:
+    # Copy the CodeBlock/Callee/ArgumentCount/|this| from protoCallFrame into the callee frame.
     subi 1, t3
     loadq [protoCallFrame, t3, 8], extraTempReg
     storeq extraTempReg, CodeBlock[sp, t3, 8]
@@ -217,7 +221,7 @@ macro doVMEntry(makeCall)
     else
         storep sp, VM::topCallFrame[vm]
     end
-    storep cfr, VM::topVMEntryFrame[vm]
+    storep cfr, VM::topEntryFrame[vm]
 
     checkStackPointerAlignment(extraTempReg, 0xbad0dc02)
 
@@ -233,8 +237,8 @@ macro doVMEntry(makeCall)
     loadp VMEntryRecord::m_vm[t4], vm
     loadp VMEntryRecord::m_prevTopCallFrame[t4], t2
     storep t2, VM::topCallFrame[vm]
-    loadp VMEntryRecord::m_prevTopVMEntryFrame[t4], t2
-    storep t2, VM::topVMEntryFrame[vm]
+    loadp VMEntryRecord::m_prevTopEntryFrame[t4], t2
+    storep t2, VM::topEntryFrame[vm]
 
     subp cfr, CalleeRegisterSaveSize, sp
 
@@ -273,11 +277,10 @@ macro makeHostFunctionCall(entry, temp)
     end
 end
 
-
 _handleUncaughtException:
     loadp Callee[cfr], t3
     andp MarkedBlockMask, t3
-    loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
+    loadp MarkedBlock::m_vm[t3], t3
     restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(t3, t0)
     loadp VM::callFrameForCatch[t3], cfr
     storep 0, VM::callFrameForCatch[t3]
@@ -288,8 +291,8 @@ _handleUncaughtException:
     loadp VMEntryRecord::m_vm[t2], t3
     loadp VMEntryRecord::m_prevTopCallFrame[t2], extraTempReg
     storep extraTempReg, VM::topCallFrame[t3]
-    loadp VMEntryRecord::m_prevTopVMEntryFrame[t2], extraTempReg
-    storep extraTempReg, VM::topVMEntryFrame[t3]
+    loadp VMEntryRecord::m_prevTopEntryFrame[t2], extraTempReg
+    storep extraTempReg, VM::topEntryFrame[t3]
 
     subp cfr, CalleeRegisterSaveSize, sp
 
@@ -346,12 +349,12 @@ macro callCallSlowPath(slowPath, action)
     action(r0, r1)
 end
 
-macro callWatchdogTimerHandler(throwHandler)
+macro callTrapHandler(throwHandler)
     storei PC, ArgumentCount + TagOffset[cfr]
     prepareStateForCCall()
     move cfr, a0
     move PC, a1
-    cCall2(_llint_slow_path_handle_watchdog_timer)
+    cCall2(_llint_slow_path_handle_traps)
     btpnz r0, throwHandler
     loadi ArgumentCount + TagOffset[cfr], PC
 end
@@ -373,6 +376,17 @@ macro checkSwitchToJITForLoop()
         end)
 end
 
+macro loadCaged(basePtr, mask, source, dest, scratch)
+    loadp source, dest
+    if GIGACAGE_ENABLED and not C_LOOP
+        loadp basePtr, scratch
+        btpz scratch, .done
+        andp mask, dest
+        addp scratch, dest
+    .done:
+    end
+end
+
 macro loadVariable(operand, value)
     loadisFromInstruction(operand, value)
     loadq [cfr, value, 8], value
@@ -404,16 +418,15 @@ end
 macro writeBarrierOnOperand(cellOperand)
     loadisFromInstruction(cellOperand, t1)
     loadConstantOrVariableCell(t1, t2, .writeBarrierDone)
-    skipIfIsRememberedOrInEden(t2, t1, t3, 
-        macro(cellState)
-            btbnz cellState, .writeBarrierDone
+    skipIfIsRememberedOrInEden(
+        t2,
+        macro()
             push PB, PC
             move t2, a1 # t2 can be a0 (not on 64 bits, but better safe than sorry)
             move cfr, a0
             cCall2Void(_llint_write_barrier_slow)
             pop PC, PB
-        end
-    )
+        end)
 .writeBarrierDone:
 end
 
@@ -432,9 +445,9 @@ macro writeBarrierOnGlobal(valueOperand, loadHelper)
     btpz t0, .writeBarrierDone
 
     loadHelper(t3)
-    skipIfIsRememberedOrInEden(t3, t1, t2,
-        macro(gcData)
-            btbnz gcData, .writeBarrierDone
+    skipIfIsRememberedOrInEden(
+        t3,
+        macro()
             push PB, PC
             move cfr, a0
             move t3, a1
@@ -470,6 +483,7 @@ end
 macro structureIDToStructureWithScratch(structureIDThenStructure, scratch)
     loadp CodeBlock[cfr], scratch
     loadp CodeBlock::m_vm[scratch], scratch
+    unpoison(CodeBlockPoison, scratch)
     loadp VM::heap + Heap::m_structureIDTable + StructureIDTable::m_table[scratch], scratch
     loadp [scratch, structureIDThenStructure, 8], structureIDThenStructure
 end
@@ -483,15 +497,11 @@ macro loadStructureAndClobberFirstArg(cell, structure)
     loadi JSCell::m_structureID[cell], structure
     loadp CodeBlock[cfr], cell
     loadp CodeBlock::m_vm[cell], cell
+    unpoison(CodeBlockPoison, cell)
     loadp VM::heap + Heap::m_structureIDTable + StructureIDTable::m_table[cell], cell
     loadp [cell, structure, 8], structure
 end
 
-macro storeStructureWithTypeInfo(cell, structure, scratch)
-    loadq Structure::m_blob + StructureIDBlob::u.doubleWord[structure], scratch
-    storeq scratch, JSCell::m_structureID[cell]
-end
-
 # Entrypoints into the interpreter.
 
 # Expects that CodeBlock is in t1, which is what prologue() leaves behind.
@@ -507,7 +517,7 @@ macro functionArityCheck(doneLabel, slowPath)
     jmp _llint_throw_from_slow_path_trampoline
 
 .noError:
-    loadi CommonSlowPaths::ArityCheckData::paddedStackSpace[r1], t1
+    move r1, t1 # r1 contains slotsToAdd.
     btiz t1, .continue
     loadi PayloadOffset + ArgumentCount[cfr], t2
     addi CallFrameHeaderSlots, t2
@@ -530,6 +540,10 @@ macro functionArityCheck(doneLabel, slowPath)
     move cfr, t3
     subp CalleeSaveSpaceAsVirtualRegisters * 8, t3
     addi CalleeSaveSpaceAsVirtualRegisters, t2
+    move t1, t0
+    lshiftp 3, t0
+    addp t0, cfr
+    addp t0, sp
 .copyLoop:
     loadq [t3], t0
     storeq t0, [t3, t1, 8]
@@ -544,14 +558,11 @@ macro functionArityCheck(doneLabel, slowPath)
     addp 8, t3
     baddinz 1, t2, .fillLoop
 
-    lshiftp 3, t1
-    addp t1, cfr
-    addp t1, sp
-
 .continue:
     # Reload CodeBlock and reset PC, since the slow_path clobbered them.
     loadp CodeBlock[cfr], t1
     loadp CodeBlock::m_instructions[t1], PB
+    unpoison(CodeBlockPoison, PB)
     move 0, PC
     jmp doneLabel
 end
@@ -559,7 +570,7 @@ end
 macro branchIfException(label)
     loadp Callee[cfr], t3
     andp MarkedBlockMask, t3
-    loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
+    loadp MarkedBlock::m_vm[t3], t3
     btqz VM::m_exception[t3], .noException
     jmp label
 .noException:
@@ -585,7 +596,24 @@ _llint_op_enter:
     btqnz t2, .opEnterLoop
 .opEnterDone:
     callOpcodeSlowPath(_slow_path_enter)
-    dispatch(1)
+    dispatch(constexpr op_enter_length)
+
+
+_llint_op_get_argument:
+    traceExecution()
+    loadisFromInstruction(1, t1)
+    loadisFromInstruction(2, t2)
+    loadi PayloadOffset + ArgumentCount[cfr], t0
+    bilteq t0, t2, .opGetArgumentOutOfBounds
+    loadq ThisArgumentOffset[cfr, t2, 8], t0
+    storeq t0, [cfr, t1, 8]
+    valueProfile(t0, 3, t2)
+    dispatch(constexpr op_get_argument_length)
+
+.opGetArgumentOutOfBounds:
+    storeq ValueUndefined, [cfr, t1, 8]
+    valueProfile(ValueUndefined, 3, t2)
+    dispatch(constexpr op_get_argument_length)
 
 
 _llint_op_argument_count:
@@ -595,7 +623,7 @@ _llint_op_argument_count:
     subi 1, t0
     orq TagTypeNumber, t0
     storeq t0, [cfr, t1, 8]
-    dispatch(2)
+    dispatch(constexpr op_argument_count_length)
 
 
 _llint_op_get_scope:
@@ -604,31 +632,7 @@ _llint_op_get_scope:
     loadp JSCallee::m_scope[t0], t0
     loadisFromInstruction(1, t1)
     storeq t0, [cfr, t1, 8]
-    dispatch(2)
-
-
-_llint_op_create_this:
-    traceExecution()
-    loadisFromInstruction(2, t0)
-    loadp [cfr, t0, 8], t0
-    bbneq JSCell::m_type[t0], JSFunctionType, .opCreateThisSlow
-    loadp JSFunction::m_rareData[t0], t3
-    btpz t3, .opCreateThisSlow
-    loadp FunctionRareData::m_objectAllocationProfile + ObjectAllocationProfile::m_allocator[t3], t1
-    loadp FunctionRareData::m_objectAllocationProfile + ObjectAllocationProfile::m_structure[t3], t2
-    btpz t1, .opCreateThisSlow
-    loadpFromInstruction(4, t3)
-    bpeq t3, 1, .hasSeenMultipleCallee
-    bpneq t3, t0, .opCreateThisSlow
-.hasSeenMultipleCallee:
-    allocateJSObject(t1, t2, t0, t3, .opCreateThisSlow)
-    loadisFromInstruction(1, t1)
-    storeq t0, [cfr, t1, 8]
-    dispatch(5)
-
-.opCreateThisSlow:
-    callOpcodeSlowPath(_slow_path_create_this)
-    dispatch(5)
+    dispatch(constexpr op_get_scope_length)
 
 
 _llint_op_to_this:
@@ -640,26 +644,11 @@ _llint_op_to_this:
     loadStructureWithScratch(t0, t1, t2)
     loadpFromInstruction(2, t2)
     bpneq t1, t2, .opToThisSlow
-    dispatch(4)
+    dispatch(constexpr op_to_this_length)
 
 .opToThisSlow:
     callOpcodeSlowPath(_slow_path_to_this)
-    dispatch(4)
-
-
-_llint_op_new_object:
-    traceExecution()
-    loadpFromInstruction(3, t0)
-    loadp ObjectAllocationProfile::m_allocator[t0], t1
-    loadp ObjectAllocationProfile::m_structure[t0], t2
-    allocateJSObject(t1, t2, t0, t3, .opNewObjectSlow)
-    loadisFromInstruction(1, t1)
-    storeq t0, [cfr, t1, 8]
-    dispatch(4)
-
-.opNewObjectSlow:
-    callOpcodeSlowPath(_llint_slow_path_new_object)
-    dispatch(4)
+    dispatch(constexpr op_to_this_length)
 
 
 _llint_op_check_tdz:
@@ -670,7 +659,7 @@ _llint_op_check_tdz:
     callOpcodeSlowPath(_slow_path_throw_tdz_error)
 
 .opNotTDZ:
-    dispatch(2)
+    dispatch(constexpr op_check_tdz_length)
 
 
 _llint_op_mov:
@@ -679,7 +668,7 @@ _llint_op_mov:
     loadisFromInstruction(1, t0)
     loadConstantOrVariable(t1, t2)
     storeq t2, [cfr, t0, 8]
-    dispatch(3)
+    dispatch(constexpr op_mov_length)
 
 
 _llint_op_not:
@@ -691,11 +680,11 @@ _llint_op_not:
     btqnz t2, ~1, .opNotSlow
     xorq ValueTrue, t2
     storeq t2, [cfr, t1, 8]
-    dispatch(3)
+    dispatch(constexpr op_not_length)
 
 .opNotSlow:
     callOpcodeSlowPath(_slow_path_not)
-    dispatch(3)
+    dispatch(constexpr op_not_length)
 
 
 macro equalityComparison(integerComparison, slowPath)
@@ -752,7 +741,7 @@ _llint_op_eq_null:
     loadisFromInstruction(1, t1)
     orq ValueFalse, t0
     storeq t0, [cfr, t1, 8]
-    dispatch(3)
+    dispatch(constexpr op_eq_null_length)
 
 
 _llint_op_neq_null:
@@ -761,7 +750,7 @@ _llint_op_neq_null:
     loadisFromInstruction(1, t1)
     xorq ValueTrue, t0
     storeq t0, [cfr, t1, 8]
-    dispatch(3)
+    dispatch(constexpr op_neq_null_length)
 
 
 macro strictEq(equalityOperation, slowPath)
@@ -839,11 +828,11 @@ _llint_op_to_number:
 .opToNumberIsImmediate:
     storeq t2, [cfr, t1, 8]
     valueProfile(t2, 3, t0)
-    dispatch(4)
+    dispatch(constexpr op_to_number_length)
 
 .opToNumberSlow:
     callOpcodeSlowPath(_slow_path_to_number)
-    dispatch(4)
+    dispatch(constexpr op_to_number_length)
 
 
 _llint_op_to_string:
@@ -855,33 +844,54 @@ _llint_op_to_string:
     bbneq JSCell::m_type[t0], StringType, .opToStringSlow
 .opToStringIsString:
     storeq t0, [cfr, t2, 8]
-    dispatch(3)
+    dispatch(constexpr op_to_string_length)
 
 .opToStringSlow:
     callOpcodeSlowPath(_slow_path_to_string)
-    dispatch(3)
+    dispatch(constexpr op_to_string_length)
 
 
-_llint_op_negate:
+_llint_op_to_object:
     traceExecution()
     loadisFromInstruction(2, t0)
     loadisFromInstruction(1, t1)
     loadConstantOrVariable(t0, t2)
-    bqb t2, tagTypeNumber, .opNegateNotInt
-    btiz t2, 0x7fffffff, .opNegateSlow
-    negi t2
-    orq tagTypeNumber, t2
+    btqnz t2, tagMask, .opToObjectSlow
+    bbb JSCell::m_type[t2], ObjectType, .opToObjectSlow
     storeq t2, [cfr, t1, 8]
-    dispatch(3)
+    valueProfile(t2, 4, t0)
+    dispatch(constexpr op_to_object_length)
+
+.opToObjectSlow:
+    callOpcodeSlowPath(_slow_path_to_object)
+    dispatch(constexpr op_to_object_length)
+
+
+_llint_op_negate:
+    traceExecution()
+    loadisFromInstruction(2, t0)
+    loadisFromInstruction(1, t1)
+    loadConstantOrVariable(t0, t3)
+    loadisFromInstruction(3, t2)
+    bqb t3, tagTypeNumber, .opNegateNotInt
+    btiz t3, 0x7fffffff, .opNegateSlow
+    negi t3
+    ori ArithProfileInt, t2
+    orq tagTypeNumber, t3
+    storeisToInstruction(t2, 3)
+    storeq t3, [cfr, t1, 8]
+    dispatch(constexpr op_negate_length)
 .opNegateNotInt:
-    btqz t2, tagTypeNumber, .opNegateSlow
-    xorq 0x8000000000000000, t2
-    storeq t2, [cfr, t1, 8]
-    dispatch(3)
+    btqz t3, tagTypeNumber, .opNegateSlow
+    xorq 0x8000000000000000, t3
+    ori ArithProfileNumber, t2
+    storeq t3, [cfr, t1, 8]
+    storeisToInstruction(t2, 3)
+    dispatch(constexpr op_negate_length)
 
 .opNegateSlow:
     callOpcodeSlowPath(_slow_path_negate)
-    dispatch(3)
+    dispatch(constexpr op_negate_length)
 
 
 macro binaryOpCustomStore(integerOperationAndStore, doubleOperation, slowPath)
@@ -893,6 +903,9 @@ macro binaryOpCustomStore(integerOperationAndStore, doubleOperation, slowPath)
     bqb t1, tagTypeNumber, .op2NotInt
     loadisFromInstruction(1, t2)
     integerOperationAndStore(t1, t0, .slow, t2)
+    loadisFromInstruction(4, t1)
+    ori ArithProfileIntInt, t1
+    storeisToInstruction(t1, 4)
     dispatch(5)
 
 .op1NotInt:
@@ -902,8 +915,14 @@ macro binaryOpCustomStore(integerOperationAndStore, doubleOperation, slowPath)
     btqz t1, tagTypeNumber, .slow
     addq tagTypeNumber, t1
     fq2d t1, ft1
+    loadisFromInstruction(4, t2)
+    ori ArithProfileNumberNumber, t2
+    storeisToInstruction(t2, 4)
     jmp .op1NotIntReady
 .op1NotIntOp2Int:
+    loadisFromInstruction(4, t2)
+    ori ArithProfileNumberInt, t2
+    storeisToInstruction(t2, 4)
     ci2d t1, ft1
 .op1NotIntReady:
     loadisFromInstruction(1, t2)
@@ -919,6 +938,9 @@ macro binaryOpCustomStore(integerOperationAndStore, doubleOperation, slowPath)
     # First operand is definitely an int, the second is definitely not.
     loadisFromInstruction(1, t2)
     btqz t1, tagTypeNumber, .slow
+    loadisFromInstruction(4, t3)
+    ori ArithProfileIntNumber, t3
+    storeisToInstruction(t3, 4)
     ci2d t0, ft0
     addq tagTypeNumber, t1
     fq2d t1, ft1
@@ -1002,7 +1024,7 @@ _llint_op_div:
             _slow_path_div)
     else
         callOpcodeSlowPath(_slow_path_div)
-        dispatch(5)
+        dispatch(constexpr op_div_length)
     end
 
 
@@ -1029,7 +1051,7 @@ _llint_op_lshift:
     bitOp(
         macro (left, right) lshifti left, right end,
         _slow_path_lshift,
-        4)
+        constexpr op_lshift_length)
 
 
 _llint_op_rshift:
@@ -1037,7 +1059,7 @@ _llint_op_rshift:
     bitOp(
         macro (left, right) rshifti left, right end,
         _slow_path_rshift,
-        4)
+        constexpr op_rshift_length)
 
 
 _llint_op_urshift:
@@ -1045,7 +1067,7 @@ _llint_op_urshift:
     bitOp(
         macro (left, right) urshifti left, right end,
         _slow_path_urshift,
-        4)
+        constexpr op_urshift_length)
 
 
 _llint_op_unsigned:
@@ -1055,10 +1077,10 @@ _llint_op_unsigned:
     loadConstantOrVariable(t1, t2)
     bilt t2, 0, .opUnsignedSlow
     storeq t2, [cfr, t0, 8]
-    dispatch(3)
+    dispatch(constexpr op_unsigned_length)
 .opUnsignedSlow:
     callOpcodeSlowPath(_slow_path_unsigned)
-    dispatch(3)
+    dispatch(constexpr op_unsigned_length)
 
 
 _llint_op_bitand:
@@ -1066,7 +1088,7 @@ _llint_op_bitand:
     bitOp(
         macro (left, right) andi left, right end,
         _slow_path_bitand,
-        5)
+        constexpr op_bitand_length)
 
 
 _llint_op_bitxor:
@@ -1074,7 +1096,7 @@ _llint_op_bitxor:
     bitOp(
         macro (left, right) xori left, right end,
         _slow_path_bitxor,
-        5)
+        constexpr op_bitxor_length)
 
 
 _llint_op_bitor:
@@ -1082,36 +1104,36 @@ _llint_op_bitor:
     bitOp(
         macro (left, right) ori left, right end,
         _slow_path_bitor,
-        5)
+        constexpr op_bitor_length)
 
 
 _llint_op_overrides_has_instance:
     traceExecution()
-    loadisFromInstruction(1, t3)
+    loadisFromStruct(OpOverridesHasInstance::m_dst, t3)
 
-    loadisFromInstruction(3, t1)
+    loadisFromStruct(OpOverridesHasInstance::m_hasInstanceValue, t1)
     loadConstantOrVariable(t1, t0)
     loadp CodeBlock[cfr], t2
     loadp CodeBlock::m_globalObject[t2], t2
     loadp JSGlobalObject::m_functionProtoHasInstanceSymbolFunction[t2], t2
     bqneq t0, t2, .opOverridesHasInstanceNotDefaultSymbol
 
-    loadisFromInstruction(2, t1)
+    loadisFromStruct(OpOverridesHasInstance::m_constructor, t1)
     loadConstantOrVariable(t1, t0)
     tbz JSCell::m_flags[t0], ImplementsDefaultHasInstance, t1
     orq ValueFalse, t1
     storeq t1, [cfr, t3, 8]
-    dispatch(4)
+    dispatch(constexpr op_overrides_has_instance_length)
 
 .opOverridesHasInstanceNotDefaultSymbol:
     storeq ValueTrue, [cfr, t3, 8]
-    dispatch(4)
+    dispatch(constexpr op_overrides_has_instance_length)
 
 
 _llint_op_instanceof_custom:
     traceExecution()
     callOpcodeSlowPath(_llint_slow_path_instanceof_custom)
-    dispatch(5)
+    dispatch(constexpr op_instanceof_custom_length)
 
 
 _llint_op_is_empty:
@@ -1122,7 +1144,7 @@ _llint_op_is_empty:
     cqeq t0, ValueEmpty, t3
     orq ValueFalse, t3
     storeq t3, [cfr, t2, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_empty_length)
 
 
 _llint_op_is_undefined:
@@ -1134,12 +1156,12 @@ _llint_op_is_undefined:
     cqeq t0, ValueUndefined, t3
     orq ValueFalse, t3
     storeq t3, [cfr, t2, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_undefined_length)
 .opIsUndefinedCell:
     btbnz JSCell::m_flags[t0], MasqueradesAsUndefined, .masqueradesAsUndefined
     move ValueFalse, t1
     storeq t1, [cfr, t2, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_undefined_length)
 .masqueradesAsUndefined:
     loadStructureWithScratch(t0, t3, t1)
     loadp CodeBlock[cfr], t1
@@ -1147,7 +1169,7 @@ _llint_op_is_undefined:
     cpeq Structure::m_globalObject[t3], t1, t0
     orq ValueFalse, t0
     storeq t0, [cfr, t2, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_undefined_length)
 
 
 _llint_op_is_boolean:
@@ -1159,7 +1181,7 @@ _llint_op_is_boolean:
     tqz t0, ~1, t0
     orq ValueFalse, t0
     storeq t0, [cfr, t2, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_boolean_length)
 
 
 _llint_op_is_number:
@@ -1170,37 +1192,23 @@ _llint_op_is_number:
     tqnz t0, tagTypeNumber, t1
     orq ValueFalse, t1
     storeq t1, [cfr, t2, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_number_length)
 
 
-_llint_op_is_string:
-    traceExecution()
-    loadisFromInstruction(2, t1)
-    loadisFromInstruction(1, t2)
-    loadConstantOrVariable(t1, t0)
-    btqnz t0, tagMask, .opIsStringNotCell
-    cbeq JSCell::m_type[t0], StringType, t1
-    orq ValueFalse, t1
-    storeq t1, [cfr, t2, 8]
-    dispatch(3)
-.opIsStringNotCell:
-    storeq ValueFalse, [cfr, t2, 8]
-    dispatch(3)
-
-
-_llint_op_is_jsarray:
+_llint_op_is_cell_with_type:
     traceExecution()
+    loadisFromInstruction(3, t0)
     loadisFromInstruction(2, t1)
     loadisFromInstruction(1, t2)
-    loadConstantOrVariable(t1, t0)
-    btqnz t0, tagMask, .opIsJSArrayNotCell
-    cbeq JSCell::m_type[t0], ArrayType, t1
+    loadConstantOrVariable(t1, t3)
+    btqnz t3, tagMask, .notCellCase
+    cbeq JSCell::m_type[t3], t0, t1
     orq ValueFalse, t1
     storeq t1, [cfr, t2, 8]
-    dispatch(3)
-.opIsJSArrayNotCell:
+    dispatch(constexpr op_is_cell_with_type_length)
+.notCellCase:
     storeq ValueFalse, [cfr, t2, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_cell_with_type_length)
 
 
 _llint_op_is_object:
@@ -1212,10 +1220,10 @@ _llint_op_is_object:
     cbaeq JSCell::m_type[t0], ObjectType, t1
     orq ValueFalse, t1
     storeq t1, [cfr, t2, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_object_length)
 .opIsObjectNotCell:
     storeq ValueFalse, [cfr, t2, 8]
-    dispatch(3)
+    dispatch(constexpr op_is_object_length)
 
 
 macro loadPropertyAtVariableOffset(propertyOffsetAsInt, objectAndStorage, value)
@@ -1255,11 +1263,11 @@ _llint_op_get_by_id:
     loadPropertyAtVariableOffset(t1, t3, t0)
     storeq t0, [cfr, t2, 8]
     valueProfile(t0, 8, t1)
-    dispatch(9)
+    dispatch(constexpr op_get_by_id_length)
 
 .opGetByIdSlow:
     callOpcodeSlowPath(_llint_slow_path_get_by_id)
-    dispatch(9)
+    dispatch(constexpr op_get_by_id_length)
 
 
 _llint_op_get_by_id_proto_load:
@@ -1275,11 +1283,11 @@ _llint_op_get_by_id_proto_load:
     loadPropertyAtVariableOffset(t1, t3, t0)
     storeq t0, [cfr, t2, 8]
     valueProfile(t0, 8, t1)
-    dispatch(9)
+    dispatch(constexpr op_get_by_id_proto_load_length)
 
 .opGetByIdProtoSlow:
     callOpcodeSlowPath(_llint_slow_path_get_by_id)
-    dispatch(9)
+    dispatch(constexpr op_get_by_id_proto_load_length)
 
 
 _llint_op_get_by_id_unset:
@@ -1292,11 +1300,11 @@ _llint_op_get_by_id_unset:
     loadisFromInstruction(1, t2)
     storeq ValueUndefined, [cfr, t2, 8]
     valueProfile(ValueUndefined, 8, t1)
-    dispatch(9)
+    dispatch(constexpr op_get_by_id_unset_length)
 
 .opGetByIdUnsetSlow:
     callOpcodeSlowPath(_llint_slow_path_get_by_id)
-    dispatch(9)
+    dispatch(constexpr op_get_by_id_unset_length)
 
 
 _llint_op_get_array_length:
@@ -1309,22 +1317,21 @@ _llint_op_get_array_length:
     btiz t2, IsArray, .opGetArrayLengthSlow
     btiz t2, IndexingShapeMask, .opGetArrayLengthSlow
     loadisFromInstruction(1, t1)
-    loadp JSObject::m_butterfly[t3], t0
+    loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[t3], t0, t2)
     loadi -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t0], t0
     bilt t0, 0, .opGetArrayLengthSlow
     orq tagTypeNumber, t0
     valueProfile(t0, 8, t2)
     storeq t0, [cfr, t1, 8]
-    dispatch(9)
+    dispatch(constexpr op_get_array_length_length)
 
 .opGetArrayLengthSlow:
     callOpcodeSlowPath(_llint_slow_path_get_by_id)
-    dispatch(9)
+    dispatch(constexpr op_get_array_length_length)
 
 
 _llint_op_put_by_id:
     traceExecution()
-    writeBarrierOnOperands(1, 3)
     loadisFromInstruction(1, t3)
     loadConstantOrVariableCell(t3, t0, .opPutByIdSlow)
     loadisFromInstruction(4, t2)
@@ -1447,6 +1454,10 @@ _llint_op_put_by_id:
 
 .opPutByIdTransitionDirect:
     storei t1, JSCell::m_structureID[t0]
+    writeBarrierOnOperand(1)
+    # Reload base into t0
+    loadisFromInstruction(1, t1)
+    loadConstantOrVariable(t1, t0)
 
 .opPutByIdNotTransition:
     # The only thing live right now is t0, which holds the base.
@@ -1454,11 +1465,12 @@ _llint_op_put_by_id:
     loadConstantOrVariable(t1, t2)
     loadisFromInstruction(5, t1)
     storePropertyAtVariableOffset(t1, t0, t2)
-    dispatch(9)
+    writeBarrierOnOperands(1, 3)
+    dispatch(constexpr op_put_by_id_length)
 
 .opPutByIdSlow:
     callOpcodeSlowPath(_llint_slow_path_put_by_id)
-    dispatch(9)
+    dispatch(constexpr op_put_by_id_length)
 
 macro finishGetByVal(result, scratch)
     loadisFromInstruction(1, scratch)
@@ -1488,13 +1500,14 @@ _llint_op_get_by_val:
     loadisFromInstruction(3, t3)
     loadConstantOrVariableInt32(t3, t1, .opGetByValSlow)
     sxi2q t1, t1
-    loadp JSObject::m_butterfly[t0], t3
+    loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[t0], t3, t5)
     andi IndexingShapeMask, t2
     bieq t2, Int32Shape, .opGetByValIsContiguous
     bineq t2, ContiguousShape, .opGetByValNotContiguous
-.opGetByValIsContiguous:
 
+.opGetByValIsContiguous:
     biaeq t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t3], .opGetByValOutOfBounds
+    andi JSObject::m_butterflyIndexingMask[t0], t1
     loadisFromInstruction(1, t0)
     loadq [t3, t1, 8], t2
     btqz t2, .opGetByValOutOfBounds
@@ -1503,7 +1516,8 @@ _llint_op_get_by_val:
 .opGetByValNotContiguous:
     bineq t2, DoubleShape, .opGetByValNotDouble
     biaeq t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.publicLength[t3], .opGetByValOutOfBounds
-    loadis 8[PB, PC, 8], t0
+    andi JSObject::m_butterflyIndexingMask[t0], t1
+    loadisFromInstruction(1 ,t0)
     loadd [t3, t1, 8], ft0
     bdnequn ft0, ft0, .opGetByValOutOfBounds
     fd2q ft0, t2
@@ -1514,6 +1528,7 @@ _llint_op_get_by_val:
     subi ArrayStorageShape, t2
     bia t2, SlowPutArrayStorageShape - ArrayStorageShape, .opGetByValNotIndexedStorage
     biaeq t1, -sizeof IndexingHeader + IndexingHeader::u.lengths.vectorLength[t3], .opGetByValOutOfBounds
+    andi JSObject::m_butterflyIndexingMask[t0], t1
     loadisFromInstruction(1, t0)
     loadq ArrayStorage::m_vector[t3, t1, 8], t2
     btqz t2, .opGetByValOutOfBounds
@@ -1521,11 +1536,12 @@ _llint_op_get_by_val:
 .opGetByValDone:
     storeq t2, [cfr, t0, 8]
     valueProfile(t2, 5, t0)
-    dispatch(6)
+    dispatch(constexpr op_get_by_val_length)
 
 .opGetByValOutOfBounds:
     loadpFromInstruction(4, t0)
     storeb 1, ArrayProfile::m_outOfBounds[t0]
+    jmp .opGetByValSlow
 
 .opGetByValNotIndexedStorage:
     # First lets check if we even have a typed array. This lets us do some boilerplate up front.
@@ -1534,7 +1550,7 @@ _llint_op_get_by_val:
     bia t2, LastArrayType - FirstArrayType, .opGetByValSlow
     
     # Sweet, now we know that we have a typed array. Do some basic things now.
-    loadp JSArrayBufferView::m_vector[t0], t3
+    loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr PRIMITIVE_GIGACAGE_MASK, JSArrayBufferView::m_vector[t0], t3, t5)
     biaeq t1, JSArrayBufferView::m_length[t0], .opGetByValSlow
     
     # Now bisect through the various types. Note that we can treat Uint8ArrayType and
@@ -1596,7 +1612,7 @@ _llint_op_get_by_val:
 
 .opGetByValSlow:
     callOpcodeSlowPath(_llint_slow_path_get_by_val)
-    dispatch(6)
+    dispatch(constexpr op_get_by_val_length)
 
 
 macro contiguousPutByVal(storeCallback)
@@ -1617,7 +1633,6 @@ end
 
 macro putByVal(slowPath)
     traceExecution()
-    writeBarrierOnOperands(1, 3)
     loadisFromInstruction(1, t0)
     loadConstantOrVariableCell(t0, t1, .opPutByValSlow)
     loadpFromInstruction(4, t3)
@@ -1626,7 +1641,7 @@ macro putByVal(slowPath)
     loadisFromInstruction(2, t0)
     loadConstantOrVariableInt32(t0, t3, .opPutByValSlow)
     sxi2q t3, t3
-    loadp JSObject::m_butterfly[t1], t0
+    loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::jsValue, constexpr JSVALUE_GIGACAGE_MASK, JSObject::m_butterfly[t1], t0, t5)
     andi IndexingShapeMask, t2
     bineq t2, Int32Shape, .opPutByValNotInt32
     contiguousPutByVal(
@@ -1634,6 +1649,7 @@ macro putByVal(slowPath)
             loadConstantOrVariable(operand, scratch)
             bpb scratch, tagTypeNumber, .opPutByValSlow
             storep scratch, address
+            writeBarrierOnOperands(1, 3)
         end)
 
 .opPutByValNotInt32:
@@ -1650,6 +1666,7 @@ macro putByVal(slowPath)
             bdnequn ft0, ft0, .opPutByValSlow
         .ready:
             stored ft0, address
+            writeBarrierOnOperands(1, 3)
         end)
 
 .opPutByValNotDouble:
@@ -1658,6 +1675,7 @@ macro putByVal(slowPath)
         macro (operand, scratch, address)
             loadConstantOrVariable(operand, scratch)
             storep scratch, address
+            writeBarrierOnOperands(1, 3)
         end)
 
 .opPutByValNotContiguous:
@@ -1668,6 +1686,7 @@ macro putByVal(slowPath)
     loadisFromInstruction(3, t2)
     loadConstantOrVariable(t2, t1)
     storeq t1, ArrayStorage::m_vector[t0, t3, 8]
+    writeBarrierOnOperands(1, 3)
     dispatch(5)
 
 .opPutByValArrayStorageEmpty:
@@ -1767,9 +1786,10 @@ _llint_op_jneq_ptr:
     loadp CodeBlock::m_globalObject[t2], t2
     loadp JSGlobalObject::m_specialPointers[t2, t1, 8], t1
     bpneq t1, [cfr, t0, 8], .opJneqPtrTarget
-    dispatch(4)
+    dispatch(5)
 
 .opJneqPtrTarget:
+    storei 1, 32[PB, PC, 8]
     dispatchIntIndirect(3)
 
 
@@ -1815,6 +1835,33 @@ macro compare(integerCompare, doubleCompare, slowPath)
 end
 
 
+macro compareUnsignedJump(integerCompare)
+    loadisFromInstruction(1, t2)
+    loadisFromInstruction(2, t3)
+    loadConstantOrVariable(t2, t0)
+    loadConstantOrVariable(t3, t1)
+    integerCompare(t0, t1, .jumpTarget)
+    dispatch(4)
+
+.jumpTarget:
+    dispatchIntIndirect(3)
+end
+
+
+macro compareUnsigned(integerCompareAndSet)
+    traceExecution()
+    loadisFromInstruction(3, t0)
+    loadisFromInstruction(2, t2)
+    loadisFromInstruction(1, t3)
+    loadConstantOrVariable(t0, t1)
+    loadConstantOrVariable(t2, t0)
+    integerCompareAndSet(t0, t1, t0)
+    orq ValueFalse, t0
+    storeq t0, [cfr, t3, 8]
+    dispatch(4)
+end
+
+
 _llint_op_switch_imm:
     traceExecution()
     loadisFromInstruction(3, t2)
@@ -1906,8 +1953,15 @@ macro doCall(slowPath, prepareCall)
     storei PC, ArgumentCount + TagOffset[cfr]
     storei t2, ArgumentCount + PayloadOffset[t3]
     move t3, sp
-    prepareCall(LLIntCallLinkInfo::machineCodeTarget[t1], t2, t3, t4)
-    callTargetFunction(LLIntCallLinkInfo::machineCodeTarget[t1])
+    if POISON
+        loadp _g_jitCodePoison, t2
+        xorp LLIntCallLinkInfo::machineCodeTarget[t1], t2
+        prepareCall(t2, t1, t3, t4)
+        callTargetFunction(t2)
+    else
+        prepareCall(LLIntCallLinkInfo::machineCodeTarget[t1], t2, t3, t4)
+        callTargetFunction(LLIntCallLinkInfo::machineCodeTarget[t1])
+    end
 
 .opCallSlow:
     slowPathForCall(slowPath, prepareCall)
@@ -1930,11 +1984,11 @@ _llint_op_to_primitive:
     bbaeq JSCell::m_type[t0], ObjectType, .opToPrimitiveSlowCase
 .opToPrimitiveIsImm:
     storeq t0, [cfr, t3, 8]
-    dispatch(3)
+    dispatch(constexpr op_to_primitive_length)
 
 .opToPrimitiveSlowCase:
     callOpcodeSlowPath(_slow_path_to_primitive)
-    dispatch(3)
+    dispatch(constexpr op_to_primitive_length)
 
 
 _llint_op_catch:
@@ -1945,7 +1999,7 @@ _llint_op_catch:
     # and have set VM::targetInterpreterPCForThrow.
     loadp Callee[cfr], t3
     andp MarkedBlockMask, t3
-    loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
+    loadp MarkedBlock::m_vm[t3], t3
     restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(t3, t0)
     loadp VM::callFrameForCatch[t3], cfr
     storep 0, VM::callFrameForCatch[t3]
@@ -1953,6 +2007,7 @@ _llint_op_catch:
 
     loadp CodeBlock[cfr], PB
     loadp CodeBlock::m_instructions[PB], PB
+    unpoison(CodeBlockPoison, PB)
     loadp VM::targetInterpreterPCForThrow[t3], PC
     subp PB, PC
     rshiftp 3, PC
@@ -1964,7 +2019,7 @@ _llint_op_catch:
 .isCatchableException:
     loadp Callee[cfr], t3
     andp MarkedBlockMask, t3
-    loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
+    loadp MarkedBlock::m_vm[t3], t3
 
     loadq VM::m_exception[t3], t0
     storeq 0, VM::m_exception[t3]
@@ -1976,7 +2031,10 @@ _llint_op_catch:
     storeq t3, [cfr, t2, 8]
 
     traceExecution()
-    dispatch(3)
+
+    callOpcodeSlowPath(_llint_slow_path_profile_catch)
+
+    dispatch(constexpr op_catch_length)
 
 
 _llint_op_end:
@@ -1991,7 +2049,7 @@ _llint_op_end:
 _llint_throw_from_slow_path_trampoline:
     loadp Callee[cfr], t1
     andp MarkedBlockMask, t1
-    loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t1], t1
+    loadp MarkedBlock::m_vm[t1], t1
     copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(t1, t2)
 
     callSlowPath(_llint_slow_path_handle_exception)
@@ -2001,7 +2059,7 @@ _llint_throw_from_slow_path_trampoline:
     # This essentially emulates the JIT's throwing protocol.
     loadp Callee[cfr], t1
     andp MarkedBlockMask, t1
-    loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t1], t1
+    loadp MarkedBlock::m_vm[t1], t1
     jmp VM::targetMachinePCForThrow[t1]
 
 
@@ -2016,7 +2074,7 @@ macro nativeCallTrampoline(executableOffsetToFunction)
     storep 0, CodeBlock[cfr]
     loadp Callee[cfr], t0
     andp MarkedBlockMask, t0, t1
-    loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t1], t1
+    loadp MarkedBlock::m_vm[t1], t1
     storep cfr, VM::topCallFrame[t1]
     if ARM64 or C_LOOP
         storep lr, ReturnPC[cfr]
@@ -2026,28 +2084,75 @@ macro nativeCallTrampoline(executableOffsetToFunction)
     loadp JSFunction::m_executable[t1], t1
     checkStackPointerAlignment(t3, 0xdead0001)
     if C_LOOP
-        cloopCallNative executableOffsetToFunction[t1]
+        loadp _g_nativeCodePoison, t2
+        xorp executableOffsetToFunction[t1], t2
+        cloopCallNative t2
     else
         if X86_64_WIN
             subp 32, sp
-        end
-        call executableOffsetToFunction[t1]
-        if X86_64_WIN
+            call executableOffsetToFunction[t1]
             addp 32, sp
+        else
+            loadp _g_nativeCodePoison, t2
+            xorp executableOffsetToFunction[t1], t2
+            call t2
         end
     end
+
     loadp Callee[cfr], t3
     andp MarkedBlockMask, t3
-    loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
+    loadp MarkedBlock::m_vm[t3], t3
+
+    btqnz VM::m_exception[t3], .handleException
 
     functionEpilogue()
+    ret
+
+.handleException:
+    storep cfr, VM::topCallFrame[t3]
+    jmp _llint_throw_from_slow_path_trampoline
+end
+
+macro internalFunctionCallTrampoline(offsetOfFunction)
+    functionPrologue()
+    storep 0, CodeBlock[cfr]
+    loadp Callee[cfr], t0
+    andp MarkedBlockMask, t0, t1
+    loadp MarkedBlock::m_vm[t1], t1
+    storep cfr, VM::topCallFrame[t1]
+    if ARM64 or C_LOOP
+        storep lr, ReturnPC[cfr]
+    end
+    move cfr, a0
+    loadp Callee[cfr], t1
+    checkStackPointerAlignment(t3, 0xdead0001)
+    if C_LOOP
+        loadp _g_nativeCodePoison, t2
+        xorp offsetOfFunction[t1], t2
+        cloopCallNative t2
+    else
+        if X86_64_WIN
+            subp 32, sp
+            call offsetOfFunction[t1]
+            addp 32, sp
+        else
+            loadp _g_nativeCodePoison, t2
+            xorp offsetOfFunction[t1], t2
+            call t2
+        end
+    end
+
+    loadp Callee[cfr], t3
+    andp MarkedBlockMask, t3
+    loadp MarkedBlock::m_vm[t3], t3
 
     btqnz VM::m_exception[t3], .handleException
+
+    functionEpilogue()
     ret
 
 .handleException:
     storep cfr, VM::topCallFrame[t3]
-    restoreStackPointerAfterCall()
     jmp _llint_throw_from_slow_path_trampoline
 end
 
@@ -2088,55 +2193,55 @@ _llint_op_resolve_scope:
 #rGlobalProperty:
     bineq t0, GlobalProperty, .rGlobalVar
     getConstantScope(1)
-    dispatch(7)
+    dispatch(constexpr op_resolve_scope_length)
 
 .rGlobalVar:
     bineq t0, GlobalVar, .rGlobalLexicalVar
     getConstantScope(1)
-    dispatch(7)
+    dispatch(constexpr op_resolve_scope_length)
 
 .rGlobalLexicalVar:
     bineq t0, GlobalLexicalVar, .rClosureVar
     getConstantScope(1)
-    dispatch(7)
+    dispatch(constexpr op_resolve_scope_length)
 
 .rClosureVar:
     bineq t0, ClosureVar, .rModuleVar
     resolveScope()
-    dispatch(7)
+    dispatch(constexpr op_resolve_scope_length)
 
 .rModuleVar:
     bineq t0, ModuleVar, .rGlobalPropertyWithVarInjectionChecks
     getConstantScope(1)
-    dispatch(7)
+    dispatch(constexpr op_resolve_scope_length)
 
 .rGlobalPropertyWithVarInjectionChecks:
     bineq t0, GlobalPropertyWithVarInjectionChecks, .rGlobalVarWithVarInjectionChecks
     varInjectionCheck(.rDynamic)
     getConstantScope(1)
-    dispatch(7)
+    dispatch(constexpr op_resolve_scope_length)
 
 .rGlobalVarWithVarInjectionChecks:
     bineq t0, GlobalVarWithVarInjectionChecks, .rGlobalLexicalVarWithVarInjectionChecks
     varInjectionCheck(.rDynamic)
     getConstantScope(1)
-    dispatch(7)
+    dispatch(constexpr op_resolve_scope_length)
 
 .rGlobalLexicalVarWithVarInjectionChecks:
     bineq t0, GlobalLexicalVarWithVarInjectionChecks, .rClosureVarWithVarInjectionChecks
     varInjectionCheck(.rDynamic)
     getConstantScope(1)
-    dispatch(7)
+    dispatch(constexpr op_resolve_scope_length)
 
 .rClosureVarWithVarInjectionChecks:
     bineq t0, ClosureVarWithVarInjectionChecks, .rDynamic
     varInjectionCheck(.rDynamic)
     resolveScope()
-    dispatch(7)
+    dispatch(constexpr op_resolve_scope_length)
 
 .rDynamic:
     callOpcodeSlowPath(_slow_path_resolve_scope)
-    dispatch(7)
+    dispatch(constexpr op_resolve_scope_length)
 
 
 macro loadWithStructureCheck(operand, slowPath)
@@ -2166,7 +2271,7 @@ end
 
 macro getClosureVar()
     loadisFromInstruction(6, t1)
-    loadq JSEnvironmentRecord_variables[t0, t1, 8], t0
+    loadq JSLexicalEnvironment_variables[t0, t1, 8], t0
     valueProfile(t0, 7, t1)
     loadisFromInstruction(1, t1)
     storeq t0, [cfr, t1, 8]
@@ -2181,12 +2286,12 @@ _llint_op_get_from_scope:
     bineq t0, GlobalProperty, .gGlobalVar
     loadWithStructureCheck(2, .gDynamic)
     getProperty()
-    dispatch(8)
+    dispatch(constexpr op_get_from_scope_length)
 
 .gGlobalVar:
     bineq t0, GlobalVar, .gGlobalLexicalVar
     getGlobalVar(macro(v) end)
-    dispatch(8)
+    dispatch(constexpr op_get_from_scope_length)
 
 .gGlobalLexicalVar:
     bineq t0, GlobalLexicalVar, .gClosureVar
@@ -2194,25 +2299,25 @@ _llint_op_get_from_scope:
         macro (value)
             bqeq value, ValueEmpty, .gDynamic
         end)
-    dispatch(8)
+    dispatch(constexpr op_get_from_scope_length)
 
 .gClosureVar:
     bineq t0, ClosureVar, .gGlobalPropertyWithVarInjectionChecks
     loadVariable(2, t0)
     getClosureVar()
-    dispatch(8)
+    dispatch(constexpr op_get_from_scope_length)
 
 .gGlobalPropertyWithVarInjectionChecks:
     bineq t0, GlobalPropertyWithVarInjectionChecks, .gGlobalVarWithVarInjectionChecks
     loadWithStructureCheck(2, .gDynamic)
     getProperty()
-    dispatch(8)
+    dispatch(constexpr op_get_from_scope_length)
 
 .gGlobalVarWithVarInjectionChecks:
     bineq t0, GlobalVarWithVarInjectionChecks, .gGlobalLexicalVarWithVarInjectionChecks
     varInjectionCheck(.gDynamic)
     getGlobalVar(macro(v) end)
-    dispatch(8)
+    dispatch(constexpr op_get_from_scope_length)
 
 .gGlobalLexicalVarWithVarInjectionChecks:
     bineq t0, GlobalLexicalVarWithVarInjectionChecks, .gClosureVarWithVarInjectionChecks
@@ -2221,18 +2326,18 @@ _llint_op_get_from_scope:
         macro (value)
             bqeq value, ValueEmpty, .gDynamic
         end)
-    dispatch(8)
+    dispatch(constexpr op_get_from_scope_length)
 
 .gClosureVarWithVarInjectionChecks:
     bineq t0, ClosureVarWithVarInjectionChecks, .gDynamic
     varInjectionCheck(.gDynamic)
     loadVariable(2, t0)
     getClosureVar()
-    dispatch(8)
+    dispatch(constexpr op_get_from_scope_length)
 
 .gDynamic:
     callOpcodeSlowPath(_llint_slow_path_get_from_scope)
-    dispatch(8)
+    dispatch(constexpr op_get_from_scope_length)
 
 
 macro putProperty()
@@ -2255,7 +2360,7 @@ macro putClosureVar()
     loadisFromInstruction(3, t1)
     loadConstantOrVariable(t1, t2)
     loadisFromInstruction(6, t1)
-    storeq t2, JSEnvironmentRecord_variables[t0, t1, 8]
+    storeq t2, JSLexicalEnvironment_variables[t0, t1, 8]
 end
 
 macro putLocalClosureVar()
@@ -2266,7 +2371,7 @@ macro putLocalClosureVar()
     notifyWrite(t3, .pDynamic)
 .noVariableWatchpointSet:
     loadisFromInstruction(6, t1)
-    storeq t2, JSEnvironmentRecord_variables[t0, t1, 8]
+    storeq t2, JSLexicalEnvironment_variables[t0, t1, 8]
 end
 
 macro checkTDZInGlobalPutToScopeIfNecessary()
@@ -2288,51 +2393,51 @@ _llint_op_put_to_scope:
 
 #pLocalClosureVar:
     bineq t0, LocalClosureVar, .pGlobalProperty
-    writeBarrierOnOperands(1, 3)
     loadVariable(1, t0)
     putLocalClosureVar()
-    dispatch(7)
+    writeBarrierOnOperands(1, 3)
+    dispatch(constexpr op_put_to_scope_length)
 
 .pGlobalProperty:
     bineq t0, GlobalProperty, .pGlobalVar
-    writeBarrierOnOperands(1, 3)
     loadWithStructureCheck(1, .pDynamic)
     putProperty()
-    dispatch(7)
+    writeBarrierOnOperands(1, 3)
+    dispatch(constexpr op_put_to_scope_length)
 
 .pGlobalVar:
     bineq t0, GlobalVar, .pGlobalLexicalVar
     writeBarrierOnGlobalObject(3)
     putGlobalVariable()
-    dispatch(7)
+    dispatch(constexpr op_put_to_scope_length)
 
 .pGlobalLexicalVar:
     bineq t0, GlobalLexicalVar, .pClosureVar
     writeBarrierOnGlobalLexicalEnvironment(3)
     checkTDZInGlobalPutToScopeIfNecessary()
     putGlobalVariable()
-    dispatch(7)
+    dispatch(constexpr op_put_to_scope_length)
 
 .pClosureVar:
     bineq t0, ClosureVar, .pGlobalPropertyWithVarInjectionChecks
-    writeBarrierOnOperands(1, 3)
     loadVariable(1, t0)
     putClosureVar()
-    dispatch(7)
+    writeBarrierOnOperands(1, 3)
+    dispatch(constexpr op_put_to_scope_length)
 
 .pGlobalPropertyWithVarInjectionChecks:
     bineq t0, GlobalPropertyWithVarInjectionChecks, .pGlobalVarWithVarInjectionChecks
-    writeBarrierOnOperands(1, 3)
     loadWithStructureCheck(1, .pDynamic)
     putProperty()
-    dispatch(7)
+    writeBarrierOnOperands(1, 3)
+    dispatch(constexpr op_put_to_scope_length)
 
 .pGlobalVarWithVarInjectionChecks:
     bineq t0, GlobalVarWithVarInjectionChecks, .pGlobalLexicalVarWithVarInjectionChecks
     writeBarrierOnGlobalObject(3)
     varInjectionCheck(.pDynamic)
     putGlobalVariable()
-    dispatch(7)
+    dispatch(constexpr op_put_to_scope_length)
 
 .pGlobalLexicalVarWithVarInjectionChecks:
     bineq t0, GlobalLexicalVarWithVarInjectionChecks, .pClosureVarWithVarInjectionChecks
@@ -2340,24 +2445,24 @@ _llint_op_put_to_scope:
     varInjectionCheck(.pDynamic)
     checkTDZInGlobalPutToScopeIfNecessary()
     putGlobalVariable()
-    dispatch(7)
+    dispatch(constexpr op_put_to_scope_length)
 
 .pClosureVarWithVarInjectionChecks:
     bineq t0, ClosureVarWithVarInjectionChecks, .pModuleVar
-    writeBarrierOnOperands(1, 3)
     varInjectionCheck(.pDynamic)
     loadVariable(1, t0)
     putClosureVar()
-    dispatch(7)
+    writeBarrierOnOperands(1, 3)
+    dispatch(constexpr op_put_to_scope_length)
 
 .pModuleVar:
     bineq t0, ModuleVar, .pDynamic
     callOpcodeSlowPath(_slow_path_throw_strict_mode_readonly_property_write_error)
-    dispatch(7)
+    dispatch(constexpr op_put_to_scope_length)
 
 .pDynamic:
     callOpcodeSlowPath(_llint_slow_path_put_to_scope)
-    dispatch(7)
+    dispatch(constexpr op_put_to_scope_length)
 
 
 _llint_op_get_from_arguments:
@@ -2368,18 +2473,18 @@ _llint_op_get_from_arguments:
     valueProfile(t0, 4, t1)
     loadisFromInstruction(1, t1)
     storeq t0, [cfr, t1, 8]
-    dispatch(5)
+    dispatch(constexpr op_get_from_arguments_length)
 
 
 _llint_op_put_to_arguments:
     traceExecution()
-    writeBarrierOnOperands(1, 3)
     loadVariable(1, t0)
     loadi 16[PB, PC, 8], t1
     loadisFromInstruction(3, t3)
     loadConstantOrVariable(t3, t2)
     storeq t2, DirectArguments_storage[t0, t1, 8]
-    dispatch(4)
+    writeBarrierOnOperands(1, 3)
+    dispatch(constexpr op_put_to_arguments_length)
 
 
 _llint_op_get_parent_scope:
@@ -2388,13 +2493,14 @@ _llint_op_get_parent_scope:
     loadp JSScope::m_next[t0], t0
     loadisFromInstruction(1, t1)
     storeq t0, [cfr, t1, 8]
-    dispatch(3)
+    dispatch(constexpr op_get_parent_scope_length)
 
 
 _llint_op_profile_type:
     traceExecution()
     loadp CodeBlock[cfr], t1
     loadp CodeBlock::m_vm[t1], t1
+    unpoison(CodeBlockPoison, t1)
     # t1 is holding the pointer to the typeProfilerLog.
     loadp VM::m_typeProfilerLog[t1], t1
     # t2 is holding the pointer to the current log entry.
@@ -2429,13 +2535,13 @@ _llint_op_profile_type:
     callOpcodeSlowPath(_slow_path_profile_type_clear_log)
 
 .opProfileTypeDone:
-    dispatch(6)
+    dispatch(constexpr op_profile_type_length)
 
 _llint_op_profile_control_flow:
     traceExecution()
     loadpFromInstruction(1, t0)
     addq 1, BasicBlockLocation::m_executionCount[t0]
-    dispatch(2)
+    dispatch(constexpr op_profile_control_flow_length)
 
 
 _llint_op_get_rest_length:
@@ -2452,7 +2558,7 @@ _llint_op_get_rest_length:
     orq tagTypeNumber, t0
     loadisFromInstruction(1, t1)
     storeq t0, [cfr, t1, 8]
-    dispatch(3)
+    dispatch(constexpr op_get_rest_length_length)
 
 
 _llint_op_log_shadow_chicken_prologue:
@@ -2465,10 +2571,10 @@ _llint_op_log_shadow_chicken_prologue:
     storep t1, ShadowChicken::Packet::callee[t0]
     loadVariable(1, t1)
     storep t1, ShadowChicken::Packet::scope[t0]
-    dispatch(2)
+    dispatch(constexpr op_log_shadow_chicken_prologue_length)
 .opLogShadowChickenPrologueSlow:
     callOpcodeSlowPath(_llint_slow_path_log_shadow_chicken_prologue)
-    dispatch(2)
+    dispatch(constexpr op_log_shadow_chicken_prologue_length)
 
 
 _llint_op_log_shadow_chicken_tail:
@@ -2483,7 +2589,7 @@ _llint_op_log_shadow_chicken_tail:
     loadp CodeBlock[cfr], t1
     storep t1, ShadowChicken::Packet::codeBlock[t0]
     storei PC, ShadowChicken::Packet::callSiteIndex[t0]
-    dispatch(3)
+    dispatch(constexpr op_log_shadow_chicken_tail_length)
 .opLogShadowChickenTailSlow:
     callOpcodeSlowPath(_llint_slow_path_log_shadow_chicken_tail)
-    dispatch(3)
+    dispatch(constexpr op_log_shadow_chicken_tail_length)