1 # Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions
6 # 1. Redistributions of source code must retain the above copyright
7 # notice, this list of conditions and the following disclaimer.
8 # 2. Redistributions in binary form must reproduce the above copyright
9 # notice, this list of conditions and the following disclaimer in the
10 # documentation and/or other materials provided with the distribution.
12 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
13 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
16 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
22 # THE POSSIBILITY OF SUCH DAMAGE.
25 # Some value representation constants.
26 const TagBitTypeOther = 0x2
27 const TagBitBool = 0x4
28 const TagBitUndefined = 0x8
29 const ValueEmpty = 0x0
30 const ValueFalse = TagBitTypeOther | TagBitBool
31 const ValueTrue = TagBitTypeOther | TagBitBool | 1
32 const ValueUndefined = TagBitTypeOther | TagBitUndefined
33 const ValueNull = TagBitTypeOther
36 macro jumpToInstruction()
40 macro dispatch(advance)
45 macro dispatchInt(advance)
50 macro dispatchIntIndirect(offset)
51 dispatchInt(offset * 8[PB, PC, 8])
54 macro dispatchAfterCall()
55 loadi ArgumentCount + TagOffset[cfr], PC
56 loadp CodeBlock[cfr], PB
57 loadp CodeBlock::m_instructions[PB], PB
61 macro cCall2(function, arg1, arg2)
71 cloopCallSlowPath function, arg1, arg2
77 # This barely works. arg3 and arg4 should probably be immediates.
78 macro cCall4(function, arg1, arg2, arg3, arg4)
98 macro prepareStateForCCall()
106 macro restoreStateAfterCCall()
114 macro callSlowPath(slowPath)
115 prepareStateForCCall()
116 cCall2(slowPath, cfr, PC)
117 restoreStateAfterCCall()
120 macro traceOperand(fromWhere, operand)
121 prepareStateForCCall()
122 cCall4(_llint_trace_operand, cfr, PC, fromWhere, operand)
123 restoreStateAfterCCall()
126 macro traceValue(fromWhere, operand)
127 prepareStateForCCall()
128 cCall4(_llint_trace_value, cfr, PC, fromWhere, operand)
129 restoreStateAfterCCall()
132 # Call a slow path for call call opcodes.
133 macro callCallSlowPath(advance, slowPath, action)
135 storei t0, ArgumentCount + TagOffset[cfr]
136 prepareStateForCCall()
137 cCall2(slowPath, cfr, PC)
142 macro callWatchdogTimerHandler(throwHandler)
143 storei PC, ArgumentCount + TagOffset[cfr]
144 prepareStateForCCall()
145 cCall2(_llint_slow_path_handle_watchdog_timer, cfr, PC)
147 btpnz t0, throwHandler
149 loadi ArgumentCount + TagOffset[cfr], PC
152 macro checkSwitchToJITForLoop()
156 storei PC, ArgumentCount + TagOffset[cfr]
157 prepareStateForCCall()
158 cCall2(_llint_loop_osr, cfr, PC)
164 loadi ArgumentCount + TagOffset[cfr], PC
168 # Index and value must be different registers. Index may be clobbered.
169 macro loadConstantOrVariable(index, value)
170 bpgteq index, FirstConstantRegisterIndex, .constant
171 loadq [cfr, index, 8], value
174 loadp CodeBlock[cfr], value
175 loadp CodeBlock::m_constantRegisters + VectorBufferOffset[value], value
176 subp FirstConstantRegisterIndex, index
177 loadq [value, index, 8], value
181 macro loadConstantOrVariableInt32(index, value, slow)
182 loadConstantOrVariable(index, value)
183 bqb value, tagTypeNumber, slow
186 macro loadConstantOrVariableCell(index, value, slow)
187 loadConstantOrVariable(index, value)
188 btqnz value, tagMask, slow
191 macro writeBarrier(value)
192 # Nothing to do, since we don't have a generational or incremental collector.
195 macro valueProfile(value, profile)
197 storeq value, ValueProfile::m_buckets[profile]
202 # Entrypoints into the interpreter.
204 # Expects that CodeBlock is in t1, which is what prologue() leaves behind.
205 macro functionArityCheck(doneLabel, slow_path)
206 loadi PayloadOffset + ArgumentCount[cfr], t0
207 biaeq t0, CodeBlock::m_numParameters[t1], doneLabel
208 prepareStateForCCall()
209 cCall2(slow_path, cfr, PC) # This slow_path has a simple protocol: t0 = 0 => no error, t0 != 0 => error
212 loadp JITStackFrame::vm[sp], t1
213 loadp VM::callFrameForThrow[t1], t0
214 jmp VM::targetMachinePCForThrow[t1]
216 # Reload CodeBlock and reset PC, since the slow_path clobbered them.
217 loadp CodeBlock[cfr], t1
218 loadp CodeBlock::m_instructions[t1], PB
224 # Instruction implementations
228 loadp CodeBlock[cfr], t2 // t2<CodeBlock> = cfr.CodeBlock
229 loadi CodeBlock::m_numVars[t2], t2 // t2<size_t> = t2<CodeBlock>.m_numVars
230 btiz t2, .opEnterDone
231 move ValueUndefined, t0
234 storeq t0, [cfr, t2, 8]
235 btinz t2, .opEnterLoop
240 _llint_op_create_activation:
242 loadisFromInstruction(1, t0)
243 bqneq [cfr, t0, 8], ValueEmpty, .opCreateActivationDone
244 callSlowPath(_llint_slow_path_create_activation)
245 .opCreateActivationDone:
249 _llint_op_init_lazy_reg:
251 loadisFromInstruction(1, t0)
252 storeq ValueEmpty, [cfr, t0, 8]
256 _llint_op_create_arguments:
258 loadisFromInstruction(1, t0)
259 bqneq [cfr, t0, 8], ValueEmpty, .opCreateArgumentsDone
260 callSlowPath(_llint_slow_path_create_arguments)
261 .opCreateArgumentsDone:
265 _llint_op_create_this:
267 loadisFromInstruction(2, t0)
268 loadp [cfr, t0, 8], t0
269 loadp JSFunction::m_allocationProfile + ObjectAllocationProfile::m_allocator[t0], t1
270 loadp JSFunction::m_allocationProfile + ObjectAllocationProfile::m_structure[t0], t2
271 btpz t1, .opCreateThisSlow
272 allocateJSObject(t1, t2, t0, t3, .opCreateThisSlow)
273 loadisFromInstruction(1, t1)
274 storeq t0, [cfr, t1, 8]
278 callSlowPath(_llint_slow_path_create_this)
282 _llint_op_get_callee:
284 loadisFromInstruction(1, t0)
285 loadpFromInstruction(2, t2)
286 loadp Callee[cfr], t1
288 storep t1, [cfr, t0, 8]
292 _llint_op_convert_this:
294 loadisFromInstruction(1, t0)
295 loadq [cfr, t0, 8], t0
296 btqnz t0, tagMask, .opConvertThisSlow
297 loadp JSCell::m_structure[t0], t0
298 bbb Structure::m_typeInfo + TypeInfo::m_type[t0], ObjectType, .opConvertThisSlow
299 loadpFromInstruction(2, t1)
304 callSlowPath(_llint_slow_path_convert_this)
308 _llint_op_new_object:
310 loadpFromInstruction(3, t0)
311 loadp ObjectAllocationProfile::m_allocator[t0], t1
312 loadp ObjectAllocationProfile::m_structure[t0], t2
313 allocateJSObject(t1, t2, t0, t3, .opNewObjectSlow)
314 loadisFromInstruction(1, t1)
315 storeq t0, [cfr, t1, 8]
319 callSlowPath(_llint_slow_path_new_object)
325 loadisFromInstruction(2, t1)
326 loadisFromInstruction(1, t0)
327 loadConstantOrVariable(t1, t2)
328 storeq t2, [cfr, t0, 8]
334 loadisFromInstruction(2, t0)
335 loadisFromInstruction(1, t1)
336 loadConstantOrVariable(t0, t2)
338 btqnz t2, ~1, .opNotSlow
340 storeq t2, [cfr, t1, 8]
344 callSlowPath(_llint_slow_path_not)
348 macro equalityComparison(integerComparison, slowPath)
350 loadisFromInstruction(3, t0)
351 loadisFromInstruction(2, t2)
352 loadisFromInstruction(1, t3)
353 loadConstantOrVariableInt32(t0, t1, .slow)
354 loadConstantOrVariableInt32(t2, t0, .slow)
355 integerComparison(t0, t1, t0)
357 storeq t0, [cfr, t3, 8]
361 callSlowPath(slowPath)
367 macro (left, right, result) cieq left, right, result end,
373 macro (left, right, result) cineq left, right, result end,
374 _llint_slow_path_neq)
377 macro equalNullComparison()
378 loadisFromInstruction(2, t0)
379 loadq [cfr, t0, 8], t0
380 btqnz t0, tagMask, .immediate
381 loadp JSCell::m_structure[t0], t2
382 btbnz Structure::m_typeInfo + TypeInfo::m_flags[t2], MasqueradesAsUndefined, .masqueradesAsUndefined
385 .masqueradesAsUndefined:
386 loadp CodeBlock[cfr], t0
387 loadp CodeBlock::m_globalObject[t0], t0
388 cpeq Structure::m_globalObject[t2], t0, t0
391 andq ~TagBitUndefined, t0
392 cqeq t0, ValueNull, t0
398 equalNullComparison()
399 loadisFromInstruction(1, t1)
401 storeq t0, [cfr, t1, 8]
407 equalNullComparison()
408 loadisFromInstruction(1, t1)
410 storeq t0, [cfr, t1, 8]
414 macro strictEq(equalityOperation, slowPath)
416 loadisFromInstruction(3, t0)
417 loadisFromInstruction(2, t2)
418 loadConstantOrVariable(t0, t1)
419 loadConstantOrVariable(t2, t0)
422 btqz t2, tagMask, .slow
423 bqaeq t0, tagTypeNumber, .leftOK
424 btqnz t0, tagTypeNumber, .slow
426 bqaeq t1, tagTypeNumber, .rightOK
427 btqnz t1, tagTypeNumber, .slow
429 equalityOperation(t0, t1, t0)
430 loadisFromInstruction(1, t1)
432 storeq t0, [cfr, t1, 8]
436 callSlowPath(slowPath)
442 macro (left, right, result) cqeq left, right, result end,
443 _llint_slow_path_stricteq)
448 macro (left, right, result) cqneq left, right, result end,
449 _llint_slow_path_nstricteq)
452 macro preOp(arithmeticOperation, slowPath)
454 loadisFromInstruction(1, t0)
455 loadq [cfr, t0, 8], t1
456 bqb t1, tagTypeNumber, .slow
457 arithmeticOperation(t1, .slow)
458 orq tagTypeNumber, t1
459 storeq t1, [cfr, t0, 8]
463 callSlowPath(slowPath)
469 macro (value, slow) baddio 1, value, slow end,
470 _llint_slow_path_pre_inc)
475 macro (value, slow) bsubio 1, value, slow end,
476 _llint_slow_path_pre_dec)
481 loadisFromInstruction(2, t0)
482 loadisFromInstruction(1, t1)
483 loadConstantOrVariable(t0, t2)
484 bqaeq t2, tagTypeNumber, .opToNumberIsImmediate
485 btqz t2, tagTypeNumber, .opToNumberSlow
486 .opToNumberIsImmediate:
487 storeq t2, [cfr, t1, 8]
491 callSlowPath(_llint_slow_path_to_number)
497 loadisFromInstruction(2, t0)
498 loadisFromInstruction(1, t1)
499 loadConstantOrVariable(t0, t2)
500 bqb t2, tagTypeNumber, .opNegateNotInt
501 btiz t2, 0x7fffffff, .opNegateSlow
503 orq tagTypeNumber, t2
504 storeq t2, [cfr, t1, 8]
507 btqz t2, tagTypeNumber, .opNegateSlow
508 xorq 0x8000000000000000, t2
509 storeq t2, [cfr, t1, 8]
513 callSlowPath(_llint_slow_path_negate)
517 macro binaryOpCustomStore(integerOperationAndStore, doubleOperation, slowPath)
518 loadisFromInstruction(3, t0)
519 loadisFromInstruction(2, t2)
520 loadConstantOrVariable(t0, t1)
521 loadConstantOrVariable(t2, t0)
522 bqb t0, tagTypeNumber, .op1NotInt
523 bqb t1, tagTypeNumber, .op2NotInt
524 loadisFromInstruction(1, t2)
525 integerOperationAndStore(t1, t0, .slow, t2)
529 # First operand is definitely not an int, the second operand could be anything.
530 btqz t0, tagTypeNumber, .slow
531 bqaeq t1, tagTypeNumber, .op1NotIntOp2Int
532 btqz t1, tagTypeNumber, .slow
533 addq tagTypeNumber, t1
539 loadisFromInstruction(1, t2)
540 addq tagTypeNumber, t0
542 doubleOperation(ft1, ft0)
544 subq tagTypeNumber, t0
545 storeq t0, [cfr, t2, 8]
549 # First operand is definitely an int, the second is definitely not.
550 loadisFromInstruction(1, t2)
551 btqz t1, tagTypeNumber, .slow
553 addq tagTypeNumber, t1
555 doubleOperation(ft1, ft0)
557 subq tagTypeNumber, t0
558 storeq t0, [cfr, t2, 8]
562 callSlowPath(slowPath)
566 macro binaryOp(integerOperation, doubleOperation, slowPath)
568 macro (left, right, slow, index)
569 integerOperation(left, right, slow)
570 orq tagTypeNumber, right
571 storeq right, [cfr, index, 8]
573 doubleOperation, slowPath)
579 macro (left, right, slow) baddio left, right, slow end,
580 macro (left, right) addd left, right end,
581 _llint_slow_path_add)
587 macro (left, right, slow, index)
588 # Assume t3 is scratchable.
590 bmulio left, t3, slow
595 orq tagTypeNumber, t3
596 storeq t3, [cfr, index, 8]
598 macro (left, right) muld left, right end,
599 _llint_slow_path_mul)
605 macro (left, right, slow) bsubio left, right, slow end,
606 macro (left, right) subd left, right end,
607 _llint_slow_path_sub)
614 macro (left, right, slow, index)
615 # Assume t3 is scratchable.
617 bineq left, -1, .notNeg2TwoThe31DivByNeg1
618 bieq right, -2147483648, .slow
619 .notNeg2TwoThe31DivByNeg1:
628 orq tagTypeNumber, t0
629 storeq t0, [cfr, index, 8]
631 macro (left, right) divd left, right end,
632 _llint_slow_path_div)
634 callSlowPath(_llint_slow_path_div)
639 macro bitOp(operation, slowPath, advance)
640 loadisFromInstruction(3, t0)
641 loadisFromInstruction(2, t2)
642 loadisFromInstruction(1, t3)
643 loadConstantOrVariable(t0, t1)
644 loadConstantOrVariable(t2, t0)
645 bqb t0, tagTypeNumber, .slow
646 bqb t1, tagTypeNumber, .slow
647 operation(t1, t0, .slow)
648 orq tagTypeNumber, t0
649 storeq t0, [cfr, t3, 8]
653 callSlowPath(slowPath)
660 macro (left, right, slow) lshifti left, right end,
661 _llint_slow_path_lshift,
668 macro (left, right, slow) rshifti left, right end,
669 _llint_slow_path_rshift,
676 macro (left, right, slow)
680 _llint_slow_path_urshift,
687 macro (left, right, slow) andi left, right end,
688 _llint_slow_path_bitand,
695 macro (left, right, slow) xori left, right end,
696 _llint_slow_path_bitxor,
703 macro (left, right, slow) ori left, right end,
704 _llint_slow_path_bitor,
708 _llint_op_check_has_instance:
710 loadisFromInstruction(3, t1)
711 loadConstantOrVariableCell(t1, t0, .opCheckHasInstanceSlow)
712 loadp JSCell::m_structure[t0], t0
713 btbz Structure::m_typeInfo + TypeInfo::m_flags[t0], ImplementsDefaultHasInstance, .opCheckHasInstanceSlow
716 .opCheckHasInstanceSlow:
717 callSlowPath(_llint_slow_path_check_has_instance)
721 _llint_op_instanceof:
723 # Actually do the work.
724 loadisFromInstruction(3, t0)
725 loadisFromInstruction(1, t3)
726 loadConstantOrVariableCell(t0, t1, .opInstanceofSlow)
727 loadp JSCell::m_structure[t1], t2
728 bbb Structure::m_typeInfo + TypeInfo::m_type[t2], ObjectType, .opInstanceofSlow
729 loadisFromInstruction(2, t0)
730 loadConstantOrVariableCell(t0, t2, .opInstanceofSlow)
732 # Register state: t1 = prototype, t2 = value
735 loadp JSCell::m_structure[t2], t2
736 loadq Structure::m_prototype[t2], t2
737 bqeq t2, t1, .opInstanceofDone
738 btqz t2, tagMask, .opInstanceofLoop
743 storeq t0, [cfr, t3, 8]
747 callSlowPath(_llint_slow_path_instanceof)
751 _llint_op_is_undefined:
753 loadisFromInstruction(2, t1)
754 loadisFromInstruction(1, t2)
755 loadConstantOrVariable(t1, t0)
756 btqz t0, tagMask, .opIsUndefinedCell
757 cqeq t0, ValueUndefined, t3
759 storeq t3, [cfr, t2, 8]
762 loadp JSCell::m_structure[t0], t0
763 btbnz Structure::m_typeInfo + TypeInfo::m_flags[t0], MasqueradesAsUndefined, .masqueradesAsUndefined
765 storeq t1, [cfr, t2, 8]
767 .masqueradesAsUndefined:
768 loadp CodeBlock[cfr], t1
769 loadp CodeBlock::m_globalObject[t1], t1
770 cpeq Structure::m_globalObject[t0], t1, t3
772 storeq t3, [cfr, t2, 8]
776 _llint_op_is_boolean:
778 loadisFromInstruction(2, t1)
779 loadisFromInstruction(1, t2)
780 loadConstantOrVariable(t1, t0)
784 storeq t0, [cfr, t2, 8]
790 loadisFromInstruction(2, t1)
791 loadisFromInstruction(1, t2)
792 loadConstantOrVariable(t1, t0)
793 tqnz t0, tagTypeNumber, t1
795 storeq t1, [cfr, t2, 8]
801 loadisFromInstruction(2, t1)
802 loadisFromInstruction(1, t2)
803 loadConstantOrVariable(t1, t0)
804 btqnz t0, tagMask, .opIsStringNotCell
805 loadp JSCell::m_structure[t0], t0
806 cbeq Structure::m_typeInfo + TypeInfo::m_type[t0], StringType, t1
808 storeq t1, [cfr, t2, 8]
811 storeq ValueFalse, [cfr, t2, 8]
815 macro loadPropertyAtVariableOffsetKnownNotInline(propertyOffsetAsPointer, objectAndStorage, value)
816 assert(macro (ok) bigteq propertyOffsetAsPointer, firstOutOfLineOffset, ok end)
817 negp propertyOffsetAsPointer
818 loadp JSObject::m_butterfly[objectAndStorage], objectAndStorage
819 loadq (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffsetAsPointer, 8], value
822 macro loadPropertyAtVariableOffset(propertyOffsetAsInt, objectAndStorage, value)
823 bilt propertyOffsetAsInt, firstOutOfLineOffset, .isInline
824 loadp JSObject::m_butterfly[objectAndStorage], objectAndStorage
825 negi propertyOffsetAsInt
826 sxi2q propertyOffsetAsInt, propertyOffsetAsInt
829 addp sizeof JSObject - (firstOutOfLineOffset - 2) * 8, objectAndStorage
831 loadq (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffsetAsInt, 8], value
834 _llint_op_init_global_const:
836 loadisFromInstruction(2, t1)
837 loadpFromInstruction(1, t0)
838 loadConstantOrVariable(t1, t2)
844 _llint_op_init_global_const_check:
846 loadpFromInstruction(3, t2)
847 loadisFromInstruction(2, t1)
848 loadpFromInstruction(1, t0)
849 btbnz [t2], .opInitGlobalConstCheckSlow
850 loadConstantOrVariable(t1, t2)
854 .opInitGlobalConstCheckSlow:
855 callSlowPath(_llint_slow_path_init_global_const_check)
858 macro getById(getPropertyStorage)
860 # We only do monomorphic get_by_id caching for now, and we do not modify the
861 # opcode. We do, however, allow for the cache to change anytime if fails, since
862 # ping-ponging is free. At best we get lucky and the get_by_id will continue
863 # to take fast path on the new cache. At worst we take slow path, which is what
864 # we would have been doing anyway.
865 loadisFromInstruction(2, t0)
866 loadpFromInstruction(4, t1)
867 loadConstantOrVariableCell(t0, t3, .opGetByIdSlow)
868 loadisFromInstruction(5, t2)
872 macro (propertyStorage, scratch)
873 bpneq JSCell::m_structure[t3], t1, .opGetByIdSlow
874 loadisFromInstruction(1, t1)
875 loadq [propertyStorage, t2], scratch
876 storeq scratch, [cfr, t1, 8]
877 loadpFromInstruction(8, t1)
878 valueProfile(scratch, t1)
883 callSlowPath(_llint_slow_path_get_by_id)
888 getById(withInlineStorage)
891 _llint_op_get_by_id_out_of_line:
892 getById(withOutOfLineStorage)
895 _llint_op_get_array_length:
897 loadisFromInstruction(2, t0)
898 loadpFromInstruction(4, t1)
899 loadConstantOrVariableCell(t0, t3, .opGetArrayLengthSlow)
900 loadp JSCell::m_structure[t3], t2
901 arrayProfile(t2, t1, t0)
902 btiz t2, IsArray, .opGetArrayLengthSlow
903 btiz t2, IndexingShapeMask, .opGetArrayLengthSlow
904 loadisFromInstruction(1, t1)
905 loadpFromInstruction(8, t2)
906 loadp JSObject::m_butterfly[t3], t0
907 loadi -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], t0
908 bilt t0, 0, .opGetArrayLengthSlow
909 orq tagTypeNumber, t0
911 storeq t0, [cfr, t1, 8]
914 .opGetArrayLengthSlow:
915 callSlowPath(_llint_slow_path_get_by_id)
919 _llint_op_get_arguments_length:
921 loadisFromInstruction(2, t0)
922 loadisFromInstruction(1, t1)
923 btqnz [cfr, t0, 8], .opGetArgumentsLengthSlow
924 loadi ArgumentCount + PayloadOffset[cfr], t2
926 orq tagTypeNumber, t2
927 storeq t2, [cfr, t1, 8]
930 .opGetArgumentsLengthSlow:
931 callSlowPath(_llint_slow_path_get_arguments_length)
935 macro putById(getPropertyStorage)
937 loadisFromInstruction(1, t3)
938 loadpFromInstruction(4, t1)
939 loadConstantOrVariableCell(t3, t0, .opPutByIdSlow)
940 loadisFromInstruction(3, t2)
944 macro (propertyStorage, scratch)
945 bpneq JSCell::m_structure[t0], t1, .opPutByIdSlow
946 loadisFromInstruction(5, t1)
947 loadConstantOrVariable(t2, scratch)
949 storeq scratch, [propertyStorage, t1]
955 putById(withInlineStorage)
958 callSlowPath(_llint_slow_path_put_by_id)
962 _llint_op_put_by_id_out_of_line:
963 putById(withOutOfLineStorage)
966 macro putByIdTransition(additionalChecks, getPropertyStorage)
968 loadisFromInstruction(1, t3)
969 loadpFromInstruction(4, t1)
970 loadConstantOrVariableCell(t3, t0, .opPutByIdSlow)
971 loadisFromInstruction(3, t2)
972 bpneq JSCell::m_structure[t0], t1, .opPutByIdSlow
973 additionalChecks(t1, t3)
974 loadisFromInstruction(5, t1)
978 macro (propertyStorage, scratch)
979 addp t1, propertyStorage, t3
980 loadConstantOrVariable(t2, t1)
983 loadpFromInstruction(6, t1)
984 storep t1, JSCell::m_structure[t0]
989 macro noAdditionalChecks(oldStructure, scratch)
992 macro structureChainChecks(oldStructure, scratch)
993 const protoCell = oldStructure # Reusing the oldStructure register for the proto
994 loadpFromInstruction(7, scratch)
995 assert(macro (ok) btpnz scratch, ok end)
996 loadp StructureChain::m_vector[scratch], scratch
997 assert(macro (ok) btpnz scratch, ok end)
998 bqeq Structure::m_prototype[oldStructure], ValueNull, .done
1000 loadq Structure::m_prototype[oldStructure], protoCell
1001 loadp JSCell::m_structure[protoCell], oldStructure
1002 bpneq oldStructure, [scratch], .opPutByIdSlow
1004 bqneq Structure::m_prototype[oldStructure], ValueNull, .loop
1008 _llint_op_put_by_id_transition_direct:
1009 putByIdTransition(noAdditionalChecks, withInlineStorage)
1012 _llint_op_put_by_id_transition_direct_out_of_line:
1013 putByIdTransition(noAdditionalChecks, withOutOfLineStorage)
1016 _llint_op_put_by_id_transition_normal:
1017 putByIdTransition(structureChainChecks, withInlineStorage)
1020 _llint_op_put_by_id_transition_normal_out_of_line:
1021 putByIdTransition(structureChainChecks, withOutOfLineStorage)
1024 _llint_op_get_by_val:
1026 loadisFromInstruction(2, t2)
1027 loadConstantOrVariableCell(t2, t0, .opGetByValSlow)
1028 loadp JSCell::m_structure[t0], t2
1029 loadpFromInstruction(4, t3)
1030 arrayProfile(t2, t3, t1)
1031 loadisFromInstruction(3, t3)
1032 loadConstantOrVariableInt32(t3, t1, .opGetByValSlow)
1034 loadp JSObject::m_butterfly[t0], t3
1035 andi IndexingShapeMask, t2
1036 bieq t2, Int32Shape, .opGetByValIsContiguous
1037 bineq t2, ContiguousShape, .opGetByValNotContiguous
1038 .opGetByValIsContiguous:
1040 biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t3], .opGetByValOutOfBounds
1041 loadisFromInstruction(1, t0)
1042 loadq [t3, t1, 8], t2
1043 btqz t2, .opGetByValOutOfBounds
1046 .opGetByValNotContiguous:
1047 bineq t2, DoubleShape, .opGetByValNotDouble
1048 biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t3], .opGetByValOutOfBounds
1049 loadis 8[PB, PC, 8], t0
1050 loadd [t3, t1, 8], ft0
1051 bdnequn ft0, ft0, .opGetByValOutOfBounds
1053 subq tagTypeNumber, t2
1056 .opGetByValNotDouble:
1057 subi ArrayStorageShape, t2
1058 bia t2, SlowPutArrayStorageShape - ArrayStorageShape, .opGetByValSlow
1059 biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t3], .opGetByValOutOfBounds
1060 loadisFromInstruction(1, t0)
1061 loadq ArrayStorage::m_vector[t3, t1, 8], t2
1062 btqz t2, .opGetByValOutOfBounds
1065 storeq t2, [cfr, t0, 8]
1066 loadpFromInstruction(5, t0)
1067 valueProfile(t2, t0)
1070 .opGetByValOutOfBounds:
1072 loadpFromInstruction(4, t0)
1073 storeb 1, ArrayProfile::m_outOfBounds[t0]
1076 callSlowPath(_llint_slow_path_get_by_val)
1080 _llint_op_get_argument_by_val:
1081 # FIXME: At some point we should array profile this. Right now it isn't necessary
1082 # since the DFG will never turn a get_argument_by_val into a GetByVal.
1084 loadisFromInstruction(2, t0)
1085 loadisFromInstruction(3, t1)
1086 btqnz [cfr, t0, 8], .opGetArgumentByValSlow
1087 loadConstantOrVariableInt32(t1, t2, .opGetArgumentByValSlow)
1089 loadi ArgumentCount + PayloadOffset[cfr], t1
1090 biaeq t2, t1, .opGetArgumentByValSlow
1093 loadisFromInstruction(1, t3)
1094 loadpFromInstruction(5, t1)
1095 loadq ThisArgumentOffset[cfr, t2, 8], t0
1096 storeq t0, [cfr, t3, 8]
1097 valueProfile(t0, t1)
1100 .opGetArgumentByValSlow:
1101 callSlowPath(_llint_slow_path_get_argument_by_val)
1105 _llint_op_get_by_pname:
1107 loadisFromInstruction(3, t1)
1108 loadConstantOrVariable(t1, t0)
1109 loadisFromInstruction(4, t1)
1110 assertNotConstant(t1)
1111 bqneq t0, [cfr, t1, 8], .opGetByPnameSlow
1112 loadisFromInstruction(2, t2)
1113 loadisFromInstruction(5, t3)
1114 loadConstantOrVariableCell(t2, t0, .opGetByPnameSlow)
1115 assertNotConstant(t3)
1116 loadq [cfr, t3, 8], t1
1117 loadp JSCell::m_structure[t0], t2
1118 bpneq t2, JSPropertyNameIterator::m_cachedStructure[t1], .opGetByPnameSlow
1119 loadisFromInstruction(6, t3)
1120 loadi PayloadOffset[cfr, t3, 8], t3
1122 biaeq t3, JSPropertyNameIterator::m_numCacheableSlots[t1], .opGetByPnameSlow
1123 bilt t3, JSPropertyNameIterator::m_cachedStructureInlineCapacity[t1], .opGetByPnameInlineProperty
1124 addi firstOutOfLineOffset, t3
1125 subi JSPropertyNameIterator::m_cachedStructureInlineCapacity[t1], t3
1126 .opGetByPnameInlineProperty:
1127 loadPropertyAtVariableOffset(t3, t0, t0)
1128 loadisFromInstruction(1, t1)
1129 storeq t0, [cfr, t1, 8]
1133 callSlowPath(_llint_slow_path_get_by_pname)
1137 macro contiguousPutByVal(storeCallback)
1138 biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .outOfBounds
1140 loadisFromInstruction(3, t2)
1141 storeCallback(t2, t1, [t0, t3, 8])
1145 biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValOutOfBounds
1147 loadp 32[PB, PC, 8], t2
1148 storeb 1, ArrayProfile::m_mayStoreToHole[t2]
1151 storei t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0]
1155 _llint_op_put_by_val:
1157 loadisFromInstruction(1, t0)
1158 loadConstantOrVariableCell(t0, t1, .opPutByValSlow)
1159 loadp JSCell::m_structure[t1], t2
1160 loadpFromInstruction(4, t3)
1161 arrayProfile(t2, t3, t0)
1162 loadisFromInstruction(2, t0)
1163 loadConstantOrVariableInt32(t0, t3, .opPutByValSlow)
1165 loadp JSObject::m_butterfly[t1], t0
1166 andi IndexingShapeMask, t2
1167 bineq t2, Int32Shape, .opPutByValNotInt32
1169 macro (operand, scratch, address)
1170 loadConstantOrVariable(operand, scratch)
1171 bpb scratch, tagTypeNumber, .opPutByValSlow
1172 storep scratch, address
1175 .opPutByValNotInt32:
1176 bineq t2, DoubleShape, .opPutByValNotDouble
1178 macro (operand, scratch, address)
1179 loadConstantOrVariable(operand, scratch)
1180 bqb scratch, tagTypeNumber, .notInt
1184 addp tagTypeNumber, scratch
1186 bdnequn ft0, ft0, .opPutByValSlow
1191 .opPutByValNotDouble:
1192 bineq t2, ContiguousShape, .opPutByValNotContiguous
1194 macro (operand, scratch, address)
1195 loadConstantOrVariable(operand, scratch)
1196 writeBarrier(scratch)
1197 storep scratch, address
1200 .opPutByValNotContiguous:
1201 bineq t2, ArrayStorageShape, .opPutByValSlow
1202 biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValOutOfBounds
1203 btqz ArrayStorage::m_vector[t0, t3, 8], .opPutByValArrayStorageEmpty
1204 .opPutByValArrayStorageStoreResult:
1205 loadisFromInstruction(3, t2)
1206 loadConstantOrVariable(t2, t1)
1208 storeq t1, ArrayStorage::m_vector[t0, t3, 8]
1211 .opPutByValArrayStorageEmpty:
1213 loadpFromInstruction(4, t1)
1214 storeb 1, ArrayProfile::m_mayStoreToHole[t1]
1216 addi 1, ArrayStorage::m_numValuesInVector[t0]
1217 bib t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValArrayStorageStoreResult
1219 storei t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0]
1220 jmp .opPutByValArrayStorageStoreResult
1222 .opPutByValOutOfBounds:
1224 loadpFromInstruction(4, t0)
1225 storeb 1, ArrayProfile::m_outOfBounds[t0]
1228 callSlowPath(_llint_slow_path_put_by_val)
1234 dispatchIntIndirect(1)
1237 macro jumpTrueOrFalse(conditionOp, slow)
1238 loadisFromInstruction(1, t1)
1239 loadConstantOrVariable(t1, t0)
1242 conditionOp(t0, .target)
1246 dispatchIntIndirect(2)
1254 macro equalNull(cellHandler, immediateHandler)
1255 loadisFromInstruction(1, t0)
1256 assertNotConstant(t0)
1257 loadq [cfr, t0, 8], t0
1258 btqnz t0, tagMask, .immediate
1259 loadp JSCell::m_structure[t0], t2
1260 cellHandler(t2, Structure::m_typeInfo + TypeInfo::m_flags[t2], .target)
1264 dispatchIntIndirect(2)
1267 andq ~TagBitUndefined, t0
1268 immediateHandler(t0, .target)
1275 macro (structure, value, target)
1276 btbz value, MasqueradesAsUndefined, .notMasqueradesAsUndefined
1277 loadp CodeBlock[cfr], t0
1278 loadp CodeBlock::m_globalObject[t0], t0
1279 bpeq Structure::m_globalObject[structure], t0, target
1280 .notMasqueradesAsUndefined:
1282 macro (value, target) bqeq value, ValueNull, target end)
1285 _llint_op_jneq_null:
1288 macro (structure, value, target)
1289 btbz value, MasqueradesAsUndefined, target
1290 loadp CodeBlock[cfr], t0
1291 loadp CodeBlock::m_globalObject[t0], t0
1292 bpneq Structure::m_globalObject[structure], t0, target
1294 macro (value, target) bqneq value, ValueNull, target end)
1299 loadisFromInstruction(1, t0)
1300 loadisFromInstruction(2, t1)
1301 loadp CodeBlock[cfr], t2
1302 loadp CodeBlock::m_globalObject[t2], t2
1303 loadp JSGlobalObject::m_specialPointers[t2, t1, 8], t1
1304 bpneq t1, [cfr, t0, 8], .opJneqPtrTarget
1308 dispatchIntIndirect(3)
1311 macro compare(integerCompare, doubleCompare, slowPath)
1312 loadisFromInstruction(1, t2)
1313 loadisFromInstruction(2, t3)
1314 loadConstantOrVariable(t2, t0)
1315 loadConstantOrVariable(t3, t1)
1316 bqb t0, tagTypeNumber, .op1NotInt
1317 bqb t1, tagTypeNumber, .op2NotInt
1318 integerCompare(t0, t1, .jumpTarget)
1322 btqz t0, tagTypeNumber, .slow
1323 bqb t1, tagTypeNumber, .op1NotIntOp2NotInt
1326 .op1NotIntOp2NotInt:
1327 btqz t1, tagTypeNumber, .slow
1328 addq tagTypeNumber, t1
1331 addq tagTypeNumber, t0
1333 doubleCompare(ft0, ft1, .jumpTarget)
1338 btqz t1, tagTypeNumber, .slow
1339 addq tagTypeNumber, t1
1341 doubleCompare(ft0, ft1, .jumpTarget)
1345 dispatchIntIndirect(3)
1348 callSlowPath(slowPath)
1353 _llint_op_switch_imm:
1355 loadisFromInstruction(3, t2)
1356 loadisFromInstruction(1, t3)
1357 loadConstantOrVariable(t2, t1)
1358 loadp CodeBlock[cfr], t2
1359 loadp CodeBlock::m_rareData[t2], t2
1360 muli sizeof SimpleJumpTable, t3 # FIXME: would be nice to peephole this!
1361 loadp CodeBlock::RareData::m_immediateSwitchJumpTables + VectorBufferOffset[t2], t2
1363 bqb t1, tagTypeNumber, .opSwitchImmNotInt
1364 subi SimpleJumpTable::min[t2], t1
1365 biaeq t1, SimpleJumpTable::branchOffsets + VectorSizeOffset[t2], .opSwitchImmFallThrough
1366 loadp SimpleJumpTable::branchOffsets + VectorBufferOffset[t2], t3
1367 loadis [t3, t1, 4], t1
1368 btiz t1, .opSwitchImmFallThrough
1372 btqnz t1, tagTypeNumber, .opSwitchImmSlow # Go slow if it's a double.
1373 .opSwitchImmFallThrough:
1374 dispatchIntIndirect(2)
1377 callSlowPath(_llint_slow_path_switch_imm)
1381 _llint_op_switch_char:
1383 loadisFromInstruction(3, t2)
1384 loadisFromInstruction(1, t3)
1385 loadConstantOrVariable(t2, t1)
1386 loadp CodeBlock[cfr], t2
1387 loadp CodeBlock::m_rareData[t2], t2
1388 muli sizeof SimpleJumpTable, t3
1389 loadp CodeBlock::RareData::m_characterSwitchJumpTables + VectorBufferOffset[t2], t2
1391 btqnz t1, tagMask, .opSwitchCharFallThrough
1392 loadp JSCell::m_structure[t1], t0
1393 bbneq Structure::m_typeInfo + TypeInfo::m_type[t0], StringType, .opSwitchCharFallThrough
1394 bineq JSString::m_length[t1], 1, .opSwitchCharFallThrough
1395 loadp JSString::m_value[t1], t0
1396 btpz t0, .opSwitchOnRope
1397 loadp StringImpl::m_data8[t0], t1
1398 btinz StringImpl::m_hashAndFlags[t0], HashFlags8BitBuffer, .opSwitchChar8Bit
1400 jmp .opSwitchCharReady
1404 subi SimpleJumpTable::min[t2], t0
1405 biaeq t0, SimpleJumpTable::branchOffsets + VectorSizeOffset[t2], .opSwitchCharFallThrough
1406 loadp SimpleJumpTable::branchOffsets + VectorBufferOffset[t2], t2
1407 loadis [t2, t0, 4], t1
1408 btiz t1, .opSwitchCharFallThrough
1411 .opSwitchCharFallThrough:
1412 dispatchIntIndirect(2)
1415 callSlowPath(_llint_slow_path_switch_char)
1421 loadisFromInstruction(3, t2)
1422 btiz t2, .opNewFuncUnchecked
1423 loadisFromInstruction(1, t1)
1424 btqnz [cfr, t1, 8], .opNewFuncDone
1425 .opNewFuncUnchecked:
1426 callSlowPath(_llint_slow_path_new_func)
1431 macro arrayProfileForCall()
1433 loadisFromInstruction(3, t3)
1434 loadq ThisArgumentOffset[cfr, t3, 8], t0
1435 btqnz t0, tagMask, .done
1436 loadp JSCell::m_structure[t0], t0
1437 loadpFromInstruction(5, t1)
1438 storep t0, ArrayProfile::m_lastSeenStructure[t1]
1443 macro doCall(slowPath)
1444 loadisFromInstruction(1, t0)
1445 loadpFromInstruction(4, t1)
1446 loadp LLIntCallLinkInfo::callee[t1], t2
1447 loadConstantOrVariable(t0, t3)
1448 bqneq t3, t2, .opCallSlow
1449 loadisFromInstruction(3, t3)
1453 loadp JSFunction::m_scope[t2], t0
1454 storeq t2, Callee[t3]
1455 storeq t0, ScopeChain[t3]
1456 loadisFromInstruction(-4, t2)
1457 storei PC, ArgumentCount + TagOffset[cfr]
1458 storeq cfr, CallerFrame[t3]
1459 storei t2, ArgumentCount + PayloadOffset[t3]
1461 callTargetFunction(t1)
1464 slowPathForCall(6, slowPath)
1468 _llint_op_tear_off_activation:
1470 loadisFromInstruction(1, t0)
1471 btqz [cfr, t0, 8], .opTearOffActivationNotCreated
1472 callSlowPath(_llint_slow_path_tear_off_activation)
1473 .opTearOffActivationNotCreated:
1477 _llint_op_tear_off_arguments:
1479 loadisFromInstruction(1, t0)
1480 subi 1, t0 # Get the unmodifiedArgumentsRegister
1481 btqz [cfr, t0, 8], .opTearOffArgumentsNotCreated
1482 callSlowPath(_llint_slow_path_tear_off_arguments)
1483 .opTearOffArgumentsNotCreated:
1489 checkSwitchToJITForEpilogue()
1490 loadisFromInstruction(1, t2)
1491 loadConstantOrVariable(t2, t0)
1495 _llint_op_call_put_result:
1496 loadisFromInstruction(1, t2)
1497 loadpFromInstruction(2, t3)
1498 storeq t0, [cfr, t2, 8]
1499 valueProfile(t0, t3)
1504 _llint_op_ret_object_or_this:
1506 checkSwitchToJITForEpilogue()
1507 loadisFromInstruction(1, t2)
1508 loadConstantOrVariable(t2, t0)
1509 btqnz t0, tagMask, .opRetObjectOrThisNotObject
1510 loadp JSCell::m_structure[t0], t2
1511 bbb Structure::m_typeInfo + TypeInfo::m_type[t2], ObjectType, .opRetObjectOrThisNotObject
1514 .opRetObjectOrThisNotObject:
1515 loadisFromInstruction(2, t2)
1516 loadConstantOrVariable(t2, t0)
1520 _llint_op_to_primitive:
1522 loadisFromInstruction(2, t2)
1523 loadisFromInstruction(1, t3)
1524 loadConstantOrVariable(t2, t0)
1525 btqnz t0, tagMask, .opToPrimitiveIsImm
1526 loadp JSCell::m_structure[t0], t2
1527 bbneq Structure::m_typeInfo + TypeInfo::m_type[t2], StringType, .opToPrimitiveSlowCase
1528 .opToPrimitiveIsImm:
1529 storeq t0, [cfr, t3, 8]
1532 .opToPrimitiveSlowCase:
1533 callSlowPath(_llint_slow_path_to_primitive)
1537 _llint_op_next_pname:
1539 loadisFromInstruction(3, t1)
1540 loadisFromInstruction(4, t2)
1541 assertNotConstant(t1)
1542 assertNotConstant(t2)
1543 loadi PayloadOffset[cfr, t1, 8], t0
1544 bieq t0, PayloadOffset[cfr, t2, 8], .opNextPnameEnd
1545 loadisFromInstruction(5, t2)
1546 assertNotConstant(t2)
1547 loadp [cfr, t2, 8], t2
1548 loadp JSPropertyNameIterator::m_jsStrings[t2], t3
1549 loadq [t3, t0, 8], t3
1551 storei t0, PayloadOffset[cfr, t1, 8]
1552 loadisFromInstruction(1, t1)
1553 storeq t3, [cfr, t1, 8]
1554 loadisFromInstruction(2, t3)
1555 assertNotConstant(t3)
1556 loadq [cfr, t3, 8], t3
1557 loadp JSCell::m_structure[t3], t1
1558 bpneq t1, JSPropertyNameIterator::m_cachedStructure[t2], .opNextPnameSlow
1559 loadp JSPropertyNameIterator::m_cachedPrototypeChain[t2], t0
1560 loadp StructureChain::m_vector[t0], t0
1561 btpz [t0], .opNextPnameTarget
1562 .opNextPnameCheckPrototypeLoop:
1563 bqeq Structure::m_prototype[t1], ValueNull, .opNextPnameSlow
1564 loadq Structure::m_prototype[t1], t2
1565 loadp JSCell::m_structure[t2], t1
1566 bpneq t1, [t0], .opNextPnameSlow
1568 btpnz [t0], .opNextPnameCheckPrototypeLoop
1570 dispatchIntIndirect(6)
1576 callSlowPath(_llint_slow_path_next_pname) # This either keeps the PC where it was (causing us to loop) or sets it to target.
1581 # This is where we end up from the JIT's throw trampoline (because the
1582 # machine code return address will be set to _llint_op_catch), and from
1583 # the interpreter's throw trampoline (see _llint_throw_trampoline).
1584 # The JIT throwing protocol calls for the cfr to be in t0. The throwing
1585 # code must have known that we were throwing to the interpreter, and have
1586 # set VM::targetInterpreterPCForThrow.
1588 loadp CodeBlock[cfr], PB
1589 loadp CodeBlock::m_instructions[PB], PB
1590 loadp JITStackFrame::vm[sp], t3
1591 loadp VM::targetInterpreterPCForThrow[t3], PC
1594 loadq VM::exception[t3], t0
1595 storeq 0, VM::exception[t3]
1596 loadisFromInstruction(1, t2)
1597 storeq t0, [cfr, t2, 8]
1604 checkSwitchToJITForEpilogue()
1605 loadisFromInstruction(1, t0)
1606 assertNotConstant(t0)
1607 loadq [cfr, t0, 8], t0
1611 _llint_throw_from_slow_path_trampoline:
1612 # When throwing from the interpreter (i.e. throwing from LLIntSlowPaths), so
1613 # the throw target is not necessarily interpreted code, we come to here.
1614 # This essentially emulates the JIT's throwing protocol.
1615 loadp JITStackFrame::vm[sp], t1
1616 loadp VM::callFrameForThrow[t1], t0
1617 jmp VM::targetMachinePCForThrow[t1]
1620 _llint_throw_during_call_trampoline:
1621 preserveReturnAddressAfterCall(t2)
1622 loadp JITStackFrame::vm[sp], t1
1623 loadp VM::callFrameForThrow[t1], t0
1624 jmp VM::targetMachinePCForThrow[t1]
1626 # Gives you the scope in t0, while allowing you to optionally perform additional checks on the
1627 # scopes as they are traversed. scopeCheck() is called with two arguments: the register
1628 # holding the scope, and a register that can be used for scratch. Note that this does not
1629 # use t3, so you can hold stuff in t3 if need be.
1630 macro getDeBruijnScope(deBruijinIndexOperand, scopeCheck)
1631 loadp ScopeChain[cfr], t0
1632 loadis deBruijinIndexOperand, t2
1636 loadp CodeBlock[cfr], t1
1637 bineq CodeBlock::m_codeType[t1], FunctionCode, .loop
1638 btbz CodeBlock::m_needsActivation[t1], .loop
1640 loadis CodeBlock::m_activationRegister[t1], t1
1642 # Need to conditionally skip over one scope.
1643 btpz [cfr, t1, 8], .noActivation
1645 loadp JSScope::m_next[t0], t0
1652 loadp JSScope::m_next[t0], t0
1659 _llint_op_get_scoped_var:
1661 # Operands are as follows:
1662 # pc[1]: Destination for the load
1663 # pc[2]: Index of register in the scope
1664 # 24[PB, PC, 8] De Bruijin index.
1665 getDeBruijnScope(24[PB, PC, 8], macro (scope, scratch) end)
1666 loadisFromInstruction(1, t1)
1667 loadisFromInstruction(2, t2)
1669 loadp JSVariableObject::m_registers[t0], t0
1670 loadp [t0, t2, 8], t3
1671 storep t3, [cfr, t1, 8]
1672 loadp 32[PB, PC, 8], t1
1673 valueProfile(t3, t1)
1677 _llint_op_put_scoped_var:
1679 getDeBruijnScope(16[PB, PC, 8], macro (scope, scratch) end)
1680 loadis 24[PB, PC, 8], t1
1681 loadConstantOrVariable(t1, t3)
1682 loadis 8[PB, PC, 8], t1
1684 loadp JSVariableObject::m_registers[t0], t0
1685 storep t3, [t0, t1, 8]
1688 macro nativeCallTrampoline(executableOffsetToFunction)
1689 storep 0, CodeBlock[cfr]
1691 loadp JITStackFrame::vm + 8[sp], t0
1692 storep cfr, VM::topCallFrame[t0]
1693 loadp CallerFrame[cfr], t0
1694 loadq ScopeChain[t0], t1
1695 storeq t1, ScopeChain[cfr]
1697 storep t1, ReturnPC[cfr]
1698 move cfr, t5 # t5 = rdi, so arg #1
1700 loadp Callee[cfr], t4 # t4 = rsi, so arg #2
1701 loadp JSFunction::m_executable[t4], t1
1702 move t0, cfr # Restore cfr to avoid loading from stack
1703 call executableOffsetToFunction[t1]
1705 loadp JITStackFrame::vm + 8[sp], t3
1707 loadp JITStackFrame::vm[sp], t0
1708 storep cfr, VM::topCallFrame[t0]
1709 loadp CallerFrame[cfr], t2
1710 loadp ScopeChain[t2], t1
1711 storep t1, ScopeChain[cfr]
1712 preserveReturnAddressAfterCall(t3)
1713 storep t3, ReturnPC[cfr]
1715 loadp Callee[cfr], t1
1716 loadp JSFunction::m_executable[t1], t1
1717 move t2, cfr # Restore cfr to avoid loading from stack
1718 call executableOffsetToFunction[t1]
1719 restoreReturnAddressBeforeReturn(t3)
1720 loadp JITStackFrame::vm[sp], t3
1722 loadp CallerFrame[cfr], t0
1723 loadp ScopeChain[t0], t1
1724 storep t1, ScopeChain[cfr]
1726 loadp JITStackFrame::vm[sp], t3
1727 storep cfr, VM::topCallFrame[t3]
1730 preserveReturnAddressAfterCall(t3)
1731 storep t3, ReturnPC[cfr]
1733 loadp Callee[cfr], t1
1734 loadp JSFunction::m_executable[t1], t1
1736 cloopCallNative executableOffsetToFunction[t1]
1738 restoreReturnAddressBeforeReturn(t3)
1739 loadp JITStackFrame::vm[sp], t3
1744 btqnz VM::exception[t3], .exception
1747 preserveReturnAddressAfterCall(t1) # This is really only needed on X86_64
1748 loadi ArgumentCount + TagOffset[cfr], PC
1749 loadp CodeBlock[cfr], PB
1750 loadp CodeBlock::m_instructions[PB], PB
1751 loadp JITStackFrame::vm[sp], t0
1752 storep cfr, VM::topCallFrame[t0]
1753 callSlowPath(_llint_throw_from_native_call)
1754 jmp _llint_throw_from_slow_path_trampoline