V8 Project
macro-assembler-ia32.h
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_IA32_MACRO_ASSEMBLER_IA32_H_
6 #define V8_IA32_MACRO_ASSEMBLER_IA32_H_
7 
8 #include "src/assembler.h"
9 #include "src/bailout-reason.h"
10 #include "src/frames.h"
11 #include "src/globals.h"
12 
13 namespace v8 {
14 namespace internal {
15 
16 // Convenience for platform-independent signatures. We do not normally
17 // distinguish memory operands from other operands on ia32.
19 
25 };
26 
27 
31 };
32 
33 
34 #ifdef DEBUG
35 bool AreAliased(Register reg1,
36  Register reg2,
37  Register reg3 = no_reg,
38  Register reg4 = no_reg,
39  Register reg5 = no_reg,
40  Register reg6 = no_reg,
41  Register reg7 = no_reg,
42  Register reg8 = no_reg);
43 #endif
44 
45 
46 // MacroAssembler implements a collection of frequently used macros.
47 class MacroAssembler: public Assembler {
48  public:
49  // The isolate parameter can be NULL if the macro assembler should
50  // not use isolate-dependent functionality. In this case, it's the
51  // responsibility of the caller to never invoke such function on the
52  // macro assembler.
53  MacroAssembler(Isolate* isolate, void* buffer, int size);
54 
55  void Load(Register dst, const Operand& src, Representation r);
56  void Store(Register src, const Operand& dst, Representation r);
57 
58  // Operations on roots in the root-array.
59  void LoadRoot(Register destination, Heap::RootListIndex index);
60  void StoreRoot(Register source, Register scratch, Heap::RootListIndex index);
61  void CompareRoot(Register with, Register scratch, Heap::RootListIndex index);
62  // These methods can only be used with constant roots (i.e. non-writable
63  // and not in new space).
65  void CompareRoot(const Operand& with, Heap::RootListIndex index);
66 
67  // ---------------------------------------------------------------------------
68  // GC Support
72  };
73 
74  // Record in the remembered set the fact that we have a pointer to new space
75  // at the address pointed to by the addr register. Only works if addr is not
76  // in new space.
77  void RememberedSetHelper(Register object, // Used for debug code.
78  Register addr,
79  Register scratch,
80  SaveFPRegsMode save_fp,
81  RememberedSetFinalAction and_then);
82 
83  void CheckPageFlag(Register object,
84  Register scratch,
85  int mask,
86  Condition cc,
87  Label* condition_met,
88  Label::Distance condition_met_distance = Label::kFar);
89 
92  int mask,
93  Condition cc,
94  Label* condition_met,
95  Label::Distance condition_met_distance = Label::kFar);
96 
98  Register scratch,
99  Label* if_deprecated);
100 
101  // Check if object is in new space. Jumps if the object is not in new space.
102  // The register scratch can be object itself, but scratch will be clobbered.
104  Register scratch,
105  Label* branch,
106  Label::Distance distance = Label::kFar) {
107  InNewSpace(object, scratch, zero, branch, distance);
108  }
109 
110  // Check if object is in new space. Jumps if the object is in new space.
111  // The register scratch can be object itself, but it will be clobbered.
113  Register scratch,
114  Label* branch,
115  Label::Distance distance = Label::kFar) {
116  InNewSpace(object, scratch, not_zero, branch, distance);
117  }
118 
119  // Check if an object has a given incremental marking color. Also uses ecx!
120  void HasColor(Register object,
121  Register scratch0,
122  Register scratch1,
123  Label* has_color,
124  Label::Distance has_color_distance,
125  int first_bit,
126  int second_bit);
127 
128  void JumpIfBlack(Register object,
129  Register scratch0,
130  Register scratch1,
131  Label* on_black,
132  Label::Distance on_black_distance = Label::kFar);
133 
134  // Checks the color of an object. If the object is already grey or black
135  // then we just fall through, since it is already live. If it is white and
136  // we can determine that it doesn't need to be scanned, then we just mark it
137  // black and fall through. For the rest we jump to the label so the
138  // incremental marker can fix its assumptions.
140  Register scratch1,
141  Register scratch2,
142  Label* object_is_white_and_not_data,
143  Label::Distance distance);
144 
145  // Notify the garbage collector that we wrote a pointer into an object.
146  // |object| is the object being stored into, |value| is the object being
147  // stored. value and scratch registers are clobbered by the operation.
148  // The offset is the offset from the start of the object, not the offset from
149  // the tagged HeapObject pointer. For use with FieldOperand(reg, off).
151  Register object,
152  int offset,
153  Register value,
154  Register scratch,
155  SaveFPRegsMode save_fp,
156  RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
157  SmiCheck smi_check = INLINE_SMI_CHECK,
158  PointersToHereCheck pointers_to_here_check_for_value =
160 
161  // As above, but the offset has the tag presubtracted. For use with
162  // Operand(reg, off).
164  Register context,
165  int offset,
166  Register value,
167  Register scratch,
168  SaveFPRegsMode save_fp,
169  RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
170  SmiCheck smi_check = INLINE_SMI_CHECK,
171  PointersToHereCheck pointers_to_here_check_for_value =
173  RecordWriteField(context,
174  offset + kHeapObjectTag,
175  value,
176  scratch,
177  save_fp,
178  remembered_set_action,
179  smi_check,
180  pointers_to_here_check_for_value);
181  }
182 
183  // Notify the garbage collector that we wrote a pointer into a fixed array.
184  // |array| is the array being stored into, |value| is the
185  // object being stored. |index| is the array index represented as a
186  // Smi. All registers are clobbered by the operation RecordWriteArray
187  // filters out smis so it does not update the write barrier if the
188  // value is a smi.
190  Register array,
191  Register value,
192  Register index,
193  SaveFPRegsMode save_fp,
194  RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
195  SmiCheck smi_check = INLINE_SMI_CHECK,
196  PointersToHereCheck pointers_to_here_check_for_value =
198 
199  // For page containing |object| mark region covering |address|
200  // dirty. |object| is the object being stored into, |value| is the
201  // object being stored. The address and value registers are clobbered by the
202  // operation. RecordWrite filters out smis so it does not update the
203  // write barrier if the value is a smi.
205  Register object,
206  Register address,
207  Register value,
208  SaveFPRegsMode save_fp,
209  RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
210  SmiCheck smi_check = INLINE_SMI_CHECK,
211  PointersToHereCheck pointers_to_here_check_for_value =
213 
214  // For page containing |object| mark the region covering the object's map
215  // dirty. |object| is the object being stored into, |map| is the Map object
216  // that was stored.
218  Register object,
220  Register scratch1,
221  Register scratch2,
222  SaveFPRegsMode save_fp);
223 
224  // ---------------------------------------------------------------------------
225  // Debugger Support
226 
227  void DebugBreak();
228 
229  // Generates function and stub prologue code.
230  void StubPrologue();
231  void Prologue(bool code_pre_aging);
232 
233  // Enter specific kind of exit frame. Expects the number of
234  // arguments in register eax and sets up the number of arguments in
235  // register edi and the pointer to the first argument in register
236  // esi.
237  void EnterExitFrame(bool save_doubles);
238 
239  void EnterApiExitFrame(int argc);
240 
241  // Leave the current exit frame. Expects the return value in
242  // register eax:edx (untouched) and the pointer to the first
243  // argument in register esi.
244  void LeaveExitFrame(bool save_doubles);
245 
246  // Leave the current exit frame. Expects the return value in
247  // register eax (untouched).
248  void LeaveApiExitFrame(bool restore_context);
249 
250  // Find the function context up the context chain.
251  void LoadContext(Register dst, int context_chain_length);
252 
253  // Conditionally load the cached Array transitioned map of type
254  // transitioned_kind from the native context if the map in register
255  // map_in_out is the cached Array map in the native context of
256  // expected_kind.
258  ElementsKind expected_kind,
259  ElementsKind transitioned_kind,
260  Register map_in_out,
261  Register scratch,
262  Label* no_map_match);
263 
264  // Load the global function with the given index.
265  void LoadGlobalFunction(int index, Register function);
266 
267  // Load the initial map from the global function. The registers
268  // function and map can be the same.
270 
271  // Push and pop the registers that can hold pointers.
274  // Store the value in register/immediate src in the safepoint
275  // register stack slot for register dst.
279 
283 
284  void LoadObject(Register result, Handle<Object> object) {
285  AllowDeferredHandleDereference heap_object_check;
286  if (object->IsHeapObject()) {
287  LoadHeapObject(result, Handle<HeapObject>::cast(object));
288  } else {
289  Move(result, Immediate(object));
290  }
291  }
292 
293  void CmpObject(Register reg, Handle<Object> object) {
294  AllowDeferredHandleDereference heap_object_check;
295  if (object->IsHeapObject()) {
297  } else {
298  cmp(reg, Immediate(object));
299  }
300  }
301 
302  // ---------------------------------------------------------------------------
303  // JavaScript invokes
304 
305  // Invoke the JavaScript function code by either calling or jumping.
306  void InvokeCode(Register code,
307  const ParameterCount& expected,
308  const ParameterCount& actual,
310  const CallWrapper& call_wrapper) {
311  InvokeCode(Operand(code), expected, actual, flag, call_wrapper);
312  }
313 
314  void InvokeCode(const Operand& code,
315  const ParameterCount& expected,
316  const ParameterCount& actual,
318  const CallWrapper& call_wrapper);
319 
320  // Invoke the JavaScript function in the given register. Changes the
321  // current context to the context in the function before invoking.
322  void InvokeFunction(Register function,
323  const ParameterCount& actual,
325  const CallWrapper& call_wrapper);
326 
327  void InvokeFunction(Register function,
328  const ParameterCount& expected,
329  const ParameterCount& actual,
331  const CallWrapper& call_wrapper);
332 
334  const ParameterCount& expected,
335  const ParameterCount& actual,
337  const CallWrapper& call_wrapper);
338 
339  // Invoke specified builtin JavaScript function. Adds an entry to
340  // the unresolved list if the name does not resolve.
343  const CallWrapper& call_wrapper = NullCallWrapper());
344 
345  // Store the function for the given builtin in the target register.
347 
348  // Store the code object for the given builtin in the target register.
350 
351  // Expression support
352  // cvtsi2sd instruction only writes to the low 64-bit of dst register, which
353  // hinders register renaming and makes dependence chains longer. So we use
354  // xorps to clear the dst register before cvtsi2sd to solve this issue.
355  void Cvtsi2sd(XMMRegister dst, Register src) { Cvtsi2sd(dst, Operand(src)); }
356  void Cvtsi2sd(XMMRegister dst, const Operand& src);
357 
358  // Support for constant splitting.
359  bool IsUnsafeImmediate(const Immediate& x);
360  void SafeMove(Register dst, const Immediate& x);
361  void SafePush(const Immediate& x);
362 
363  // Compare object type for heap object.
364  // Incoming register is heap_object and outgoing register is map.
365  void CmpObjectType(Register heap_object, InstanceType type, Register map);
366 
367  // Compare instance type for map.
369 
370  // Check if a map for a JSObject indicates that the object has fast elements.
371  // Jump to the specified label if it does not.
373  Label* fail,
374  Label::Distance distance = Label::kFar);
375 
376  // Check if a map for a JSObject indicates that the object can have both smi
377  // and HeapObject elements. Jump to the specified label if it does not.
379  Label* fail,
380  Label::Distance distance = Label::kFar);
381 
382  // Check if a map for a JSObject indicates that the object has fast smi only
383  // elements. Jump to the specified label if it does not.
385  Label* fail,
386  Label::Distance distance = Label::kFar);
387 
388  // Check to see if maybe_number can be stored as a double in
389  // FastDoubleElements. If it can, store it at the index specified by key in
390  // the FastDoubleElements array elements, otherwise jump to fail.
392  Register elements,
393  Register key,
394  Register scratch1,
395  XMMRegister scratch2,
396  Label* fail,
397  int offset = 0);
398 
399  // Compare an object's map with the specified map.
401 
402  // Check if the map of an object is equal to a specified map and branch to
403  // label if not. Skip the smi check if not required (object is known to be a
404  // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match
405  // against maps that are ElementsKind transition maps of the specified map.
406  void CheckMap(Register obj,
408  Label* fail,
409  SmiCheckType smi_check_type);
410 
411  // Check if the map of an object is equal to a specified map and branch to a
412  // specified target if equal. Skip the smi check if not required (object is
413  // known to be a heap object)
415  Register unused,
417  Handle<Code> success,
418  SmiCheckType smi_check_type);
419 
420  // Check if the object in register heap_object is a string. Afterwards the
421  // register map contains the object map and the register instance_type
422  // contains the instance_type. The registers map and instance_type can be the
423  // same in which case it contains the instance type afterwards. Either of the
424  // registers map and instance_type can be the same as heap_object.
426  Register map,
427  Register instance_type);
428 
429  // Check if the object in register heap_object is a name. Afterwards the
430  // register map contains the object map and the register instance_type
431  // contains the instance_type. The registers map and instance_type can be the
432  // same in which case it contains the instance type afterwards. Either of the
433  // registers map and instance_type can be the same as heap_object.
435  Register map,
436  Register instance_type);
437 
438  // Check if a heap object's type is in the JSObject range, not including
439  // JSFunction. The object's map will be loaded in the map register.
440  // Any or all of the three registers may be the same.
441  // The contents of the scratch register will always be overwritten.
442  void IsObjectJSObjectType(Register heap_object,
443  Register map,
444  Register scratch,
445  Label* fail);
446 
447  // The contents of the scratch register will be overwritten.
448  void IsInstanceJSObjectType(Register map, Register scratch, Label* fail);
449 
450  // FCmp is similar to integer cmp, but requires unsigned
451  // jcc instructions (je, ja, jae, jb, jbe, je, and jz).
452  void FCmp();
453 
454  void ClampUint8(Register reg);
455 
457  XMMRegister scratch_reg,
458  Register result_reg);
459 
460  void SlowTruncateToI(Register result_reg, Register input_reg,
462 
463  void TruncateHeapNumberToI(Register result_reg, Register input_reg);
464  void TruncateDoubleToI(Register result_reg, XMMRegister input_reg);
465 
466  void DoubleToI(Register result_reg, XMMRegister input_reg,
467  XMMRegister scratch, MinusZeroMode minus_zero_mode,
468  Label* lost_precision, Label* is_nan, Label* minus_zero,
469  Label::Distance dst = Label::kFar);
470 
471  // Smi tagging support.
472  void SmiTag(Register reg) {
473  STATIC_ASSERT(kSmiTag == 0);
475  add(reg, reg);
476  }
477  void SmiUntag(Register reg) {
478  sar(reg, kSmiTagSize);
479  }
480 
481  // Modifies the register even if it does not contain a Smi!
482  void SmiUntag(Register reg, Label* is_smi) {
484  sar(reg, kSmiTagSize);
485  STATIC_ASSERT(kSmiTag == 0);
486  j(not_carry, is_smi);
487  }
488 
490 
491  // Jump the register contains a smi.
492  inline void JumpIfSmi(Register value,
493  Label* smi_label,
494  Label::Distance distance = Label::kFar) {
495  test(value, Immediate(kSmiTagMask));
496  j(zero, smi_label, distance);
497  }
498  // Jump if the operand is a smi.
499  inline void JumpIfSmi(Operand value,
500  Label* smi_label,
501  Label::Distance distance = Label::kFar) {
502  test(value, Immediate(kSmiTagMask));
503  j(zero, smi_label, distance);
504  }
505  // Jump if register contain a non-smi.
506  inline void JumpIfNotSmi(Register value,
507  Label* not_smi_label,
508  Label::Distance distance = Label::kFar) {
509  test(value, Immediate(kSmiTagMask));
510  j(not_zero, not_smi_label, distance);
511  }
512 
516 
517  template<typename Field>
518  void DecodeField(Register reg) {
519  static const int shift = Field::kShift;
520  static const int mask = Field::kMask >> Field::kShift;
521  if (shift != 0) {
522  sar(reg, shift);
523  }
524  and_(reg, Immediate(mask));
525  }
526 
527  template<typename Field>
529  static const int shift = Field::kShift;
530  static const int mask = (Field::kMask >> Field::kShift) << kSmiTagSize;
531  STATIC_ASSERT((mask & (0x80000000u >> (kSmiTagSize - 1))) == 0);
532  STATIC_ASSERT(kSmiTag == 0);
533  if (shift < kSmiTagSize) {
534  shl(reg, kSmiTagSize - shift);
535  } else if (shift > kSmiTagSize) {
536  sar(reg, shift - kSmiTagSize);
537  }
538  and_(reg, Immediate(mask));
539  }
540 
541  void LoadPowerOf2(XMMRegister dst, Register scratch, int power);
542 
543  // Abort execution if argument is not a number, enabled via --debug-code.
544  void AssertNumber(Register object);
545 
546  // Abort execution if argument is not a smi, enabled via --debug-code.
547  void AssertSmi(Register object);
548 
549  // Abort execution if argument is a smi, enabled via --debug-code.
550  void AssertNotSmi(Register object);
551 
552  // Abort execution if argument is not a string, enabled via --debug-code.
553  void AssertString(Register object);
554 
555  // Abort execution if argument is not a name, enabled via --debug-code.
556  void AssertName(Register object);
557 
558  // Abort execution if argument is not undefined or an AllocationSite, enabled
559  // via --debug-code.
561 
562  // ---------------------------------------------------------------------------
563  // Exception handling
564 
565  // Push a new try handler and link it into try handler chain.
566  void PushTryHandler(StackHandler::Kind kind, int handler_index);
567 
568  // Unlink the stack handler on top of the stack from the try handler chain.
570 
571  // Throw to the top handler in the try hander chain.
572  void Throw(Register value);
573 
574  // Throw past all JS frames to the top JS entry frame.
576 
577  // ---------------------------------------------------------------------------
578  // Inline caching support
579 
580  // Generate code for checking access rights - used for security checks
581  // on access to global objects across environments. The holder register
582  // is left untouched, but the scratch register is clobbered.
584  Register scratch1,
585  Register scratch2,
586  Label* miss);
587 
589 
590  void LoadFromNumberDictionary(Label* miss,
591  Register elements,
592  Register key,
593  Register r0,
594  Register r1,
595  Register r2,
596  Register result);
597 
598 
599  // ---------------------------------------------------------------------------
600  // Allocation support
601 
602  // Allocate an object in new space or old pointer space. If the given space
603  // is exhausted control continues at the gc_required label. The allocated
604  // object is returned in result and end of the new object is returned in
605  // result_end. The register scratch can be passed as no_reg in which case
606  // an additional object reference will be added to the reloc info. The
607  // returned pointers in result and result_end have not yet been tagged as
608  // heap objects. If result_contains_top_on_entry is true the content of
609  // result is known to be the allocation top on entry (could be result_end
610  // from a previous call). If result_contains_top_on_entry is true scratch
611  // should be no_reg as it is never used.
612  void Allocate(int object_size,
613  Register result,
614  Register result_end,
615  Register scratch,
616  Label* gc_required,
618 
619  void Allocate(int header_size,
620  ScaleFactor element_size,
621  Register element_count,
622  RegisterValueType element_count_type,
623  Register result,
624  Register result_end,
625  Register scratch,
626  Label* gc_required,
628 
629  void Allocate(Register object_size,
630  Register result,
631  Register result_end,
632  Register scratch,
633  Label* gc_required,
635 
636  // Undo allocation in new space. The object passed and objects allocated after
637  // it will no longer be allocated. Make sure that no pointers are left to the
638  // object(s) no longer allocated as they would be invalid when allocation is
639  // un-done.
641 
642  // Allocate a heap number in new space with undefined value. The
643  // register scratch2 can be passed as no_reg; the others must be
644  // valid registers. Returns tagged pointer in result register, or
645  // jumps to gc_required if new space is full.
647  Register scratch1,
648  Register scratch2,
649  Label* gc_required,
651 
652  // Allocate a sequential string. All the header fields of the string object
653  // are initialized.
655  Register length,
656  Register scratch1,
657  Register scratch2,
658  Register scratch3,
659  Label* gc_required);
661  Register scratch1, Register scratch2,
662  Register scratch3, Label* gc_required);
663  void AllocateOneByteString(Register result, int length, Register scratch1,
664  Register scratch2, Label* gc_required);
665 
666  // Allocate a raw cons string object. Only the map field of the result is
667  // initialized.
669  Register scratch1,
670  Register scratch2,
671  Label* gc_required);
673  Register scratch2, Label* gc_required);
674 
675  // Allocate a raw sliced string object. Only the map field of the result is
676  // initialized.
678  Register scratch1,
679  Register scratch2,
680  Label* gc_required);
682  Register scratch2, Label* gc_required);
683 
684  // Copy memory, byte-by-byte, from source to destination. Not optimized for
685  // long or aligned copies.
686  // The contents of index and scratch are destroyed.
687  void CopyBytes(Register source,
688  Register destination,
689  Register length,
690  Register scratch);
691 
692  // Initialize fields with filler values. Fields starting at |start_offset|
693  // not including end_offset are overwritten with the value in |filler|. At
694  // the end the loop, |start_offset| takes the value of |end_offset|.
696  Register end_offset,
697  Register filler);
698 
699  // ---------------------------------------------------------------------------
700  // Support functions.
701 
702  // Check a boolean-bit of a Smi field.
703  void BooleanBitTest(Register object, int field_offset, int bit_index);
704 
705  // Check if result is zero and op is negative.
706  void NegativeZeroTest(Register result, Register op, Label* then_label);
707 
708  // Check if result is zero and any of op1 and op2 are negative.
709  // Register scratch is destroyed, and it must be different from op2.
711  Register scratch, Label* then_label);
712 
713  // Try to get function prototype of a function and puts the value in
714  // the result register. Checks that the function really is a
715  // function and jumps to the miss label if the fast checks fail. The
716  // function register will be untouched; the other registers may be
717  // clobbered.
719  Register result,
720  Register scratch,
721  Label* miss,
722  bool miss_on_bound_function = false);
723 
724  // Picks out an array index from the hash field.
725  // Register use:
726  // hash - holds the index's hash. Clobbered.
727  // index - holds the overwritten index on exit.
728  void IndexFromHash(Register hash, Register index);
729 
730  // ---------------------------------------------------------------------------
731  // Runtime calls
732 
733  // Call a code stub. Generate the code if necessary.
735 
736  // Tail call a code stub (jump). Generate the code if necessary.
737  void TailCallStub(CodeStub* stub);
738 
739  // Return from a code stub after popping its arguments.
740  void StubReturn(int argc);
741 
742  // Call a runtime routine.
744  int num_arguments,
745  SaveFPRegsMode save_doubles = kDontSaveFPRegs);
747  const Runtime::Function* function = Runtime::FunctionForId(id);
748  CallRuntime(function, function->nargs, kSaveFPRegs);
749  }
750 
751  // Convenience function: Same as above, but takes the fid instead.
753  int num_arguments,
754  SaveFPRegsMode save_doubles = kDontSaveFPRegs) {
755  CallRuntime(Runtime::FunctionForId(id), num_arguments, save_doubles);
756  }
757 
758  // Convenience function: call an external reference.
759  void CallExternalReference(ExternalReference ref, int num_arguments);
760 
761  // Tail call of a runtime routine (jump).
762  // Like JumpToExternalReference, but also takes care of passing the number
763  // of parameters.
764  void TailCallExternalReference(const ExternalReference& ext,
765  int num_arguments,
766  int result_size);
767 
768  // Convenience function: tail call a runtime routine (jump).
770  int num_arguments,
771  int result_size);
772 
773  // Before calling a C-function from generated code, align arguments on stack.
774  // After aligning the frame, arguments must be stored in esp[0], esp[4],
775  // etc., not pushed. The argument count assumes all arguments are word sized.
776  // Some compilers/platforms require the stack to be aligned when calling
777  // C++ code.
778  // Needs a scratch register to do some arithmetic. This register will be
779  // trashed.
780  void PrepareCallCFunction(int num_arguments, Register scratch);
781 
782  // Calls a C function and cleans up the space for arguments allocated
783  // by PrepareCallCFunction. The called function is not allowed to trigger a
784  // garbage collection, since that might move the code and invalidate the
785  // return address (unless this is somehow accounted for by the called
786  // function).
787  void CallCFunction(ExternalReference function, int num_arguments);
788  void CallCFunction(Register function, int num_arguments);
789 
790  // Prepares stack to put arguments (aligns and so on). Reserves
791  // space for return value if needed (assumes the return value is a handle).
792  // Arguments must be stored in ApiParameterOperand(0), ApiParameterOperand(1)
793  // etc. Saves context (esi). If space was reserved for return value then
794  // stores the pointer to the reserved slot into esi.
795  void PrepareCallApiFunction(int argc);
796 
797  // Calls an API function. Allocates HandleScope, extracts returned value
798  // from handle and propagates exceptions. Clobbers ebx, edi and
799  // caller-save registers. Restores context. On return removes
800  // stack_space * kPointerSize (GCed).
801  void CallApiFunctionAndReturn(Register function_address,
802  ExternalReference thunk_ref,
803  Operand thunk_last_arg,
804  int stack_space,
805  Operand return_value_operand,
806  Operand* context_restore_operand);
807 
808  // Jump to a runtime routine.
809  void JumpToExternalReference(const ExternalReference& ext);
810 
811  // ---------------------------------------------------------------------------
812  // Utilities
813 
814  void Ret();
815 
816  // Return and drop arguments from stack, where the number of arguments
817  // may be bigger than 2^16 - 1. Requires a scratch register.
818  void Ret(int bytes_dropped, Register scratch);
819 
820  // Emit code to discard a non-negative number of pointer-sized elements
821  // from the stack, clobbering only the esp register.
822  void Drop(int element_count);
823 
824  void Call(Label* target) { call(target); }
825  void Push(Register src) { push(src); }
826  void Pop(Register dst) { pop(dst); }
827 
828  // Emit call to the code we are currently generating.
829  void CallSelf() {
830  Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location()));
832  }
833 
834  // Move if the registers are not identical.
835  void Move(Register target, Register source);
836 
837  // Move a constant into a destination using the most efficient encoding.
838  void Move(Register dst, const Immediate& x);
839  void Move(const Operand& dst, const Immediate& x);
840 
841  // Move an immediate into an XMM register.
842  void Move(XMMRegister dst, double val);
843 
844  // Push a handle value.
846  void Push(Smi* smi) { Push(Handle<Smi>(smi, isolate())); }
847 
849  DCHECK(!code_object_.is_null());
850  return code_object_;
851  }
852 
853  // Emit code for a truncating division by a constant. The dividend register is
854  // unchanged, the result is in edx, and eax gets clobbered.
855  void TruncatingDiv(Register dividend, int32_t divisor);
856 
857  // ---------------------------------------------------------------------------
858  // StatsCounter support
859 
860  void SetCounter(StatsCounter* counter, int value);
861  void IncrementCounter(StatsCounter* counter, int value);
862  void DecrementCounter(StatsCounter* counter, int value);
863  void IncrementCounter(Condition cc, StatsCounter* counter, int value);
864  void DecrementCounter(Condition cc, StatsCounter* counter, int value);
865 
866 
867  // ---------------------------------------------------------------------------
868  // Debugging
869 
870  // Calls Abort(msg) if the condition cc is not satisfied.
871  // Use --debug_code to enable.
873 
874  void AssertFastElements(Register elements);
875 
876  // Like Assert(), but always enabled.
878 
879  // Print a message to stdout and abort execution.
880  void Abort(BailoutReason reason);
881 
882  // Check that the stack is aligned.
884 
885  // Verify restrictions about code generated in stubs.
886  void set_generating_stub(bool value) { generating_stub_ = value; }
888  void set_has_frame(bool value) { has_frame_ = value; }
889  bool has_frame() { return has_frame_; }
890  inline bool AllowThisStubCall(CodeStub* stub);
891 
892  // ---------------------------------------------------------------------------
893  // String utilities.
894 
895  // Generate code to do a lookup in the number string cache. If the number in
896  // the register object is found in the cache the generated code falls through
897  // with the result in the result register. The object and the result register
898  // can be the same. If the number is not found in the cache the code jumps to
899  // the label not_found with only the content of register object unchanged.
901  Register result,
902  Register scratch1,
903  Register scratch2,
904  Label* not_found);
905 
906  // Check whether the instance type represents a flat one-byte string. Jump to
907  // the label if not. If the instance type can be scratched specify same
908  // register for both instance type and scratch.
910  Register instance_type, Register scratch,
911  Label* on_not_flat_one_byte_string);
912 
913  // Checks if both objects are sequential one-byte strings, and jumps to label
914  // if either is not.
916  Register object1, Register object2, Register scratch1, Register scratch2,
917  Label* on_not_flat_one_byte_strings);
918 
919  // Checks if the given register or operand is a unique name
920  void JumpIfNotUniqueNameInstanceType(Register reg, Label* not_unique_name,
921  Label::Distance distance = Label::kFar) {
922  JumpIfNotUniqueNameInstanceType(Operand(reg), not_unique_name, distance);
923  }
924 
925  void JumpIfNotUniqueNameInstanceType(Operand operand, Label* not_unique_name,
926  Label::Distance distance = Label::kFar);
927 
929  Register index,
930  Register value,
931  uint32_t encoding_mask);
932 
934  return SafepointRegisterStackIndex(reg.code());
935  }
936 
937  // Activation support.
940 
941  // Expects object in eax and returns map with validated enum cache
942  // in eax. Assumes that any other register can be used as a scratch.
943  void CheckEnumCache(Label* call_runtime);
944 
945  // AllocationMemento support. Arrays may have an associated
946  // AllocationMemento object that can be checked for in order to pretransition
947  // to another type.
948  // On entry, receiver_reg should point to the array object.
949  // scratch_reg gets clobbered.
950  // If allocation info is present, conditional code is set to equal.
952  Register scratch_reg,
953  Label* no_memento_found);
954 
956  Register scratch_reg,
957  Label* memento_found) {
958  Label no_memento_found;
959  TestJSArrayForAllocationMemento(receiver_reg, scratch_reg,
960  &no_memento_found);
961  j(equal, memento_found);
962  bind(&no_memento_found);
963  }
964 
965  // Jumps to found label if a prototype map has dictionary elements.
967  Register scratch1, Label* found);
968 
969  private:
970  bool generating_stub_;
971  bool has_frame_;
972  // This handle will be patched with the code object on installation.
974 
975  // Helper functions for generating invokes.
976  void InvokePrologue(const ParameterCount& expected,
977  const ParameterCount& actual,
978  Handle<Code> code_constant,
979  const Operand& code_operand,
980  Label* done,
981  bool* definitely_mismatches,
983  Label::Distance done_distance,
984  const CallWrapper& call_wrapper = NullCallWrapper());
985 
987  void EnterExitFrameEpilogue(int argc, bool save_doubles);
988 
989  void LeaveExitFrameEpilogue(bool restore_context);
990 
991  // Allocation support helpers.
993  Register scratch,
995 
997  Register scratch,
999 
1000  // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace.
1001  void InNewSpace(Register object,
1002  Register scratch,
1003  Condition cc,
1004  Label* condition_met,
1005  Label::Distance condition_met_distance = Label::kFar);
1006 
1007  // Helper for finding the mark bits for an address. Afterwards, the
1008  // bitmap register points at the word with the mark bits and the mask
1009  // the position of the first bit. Uses ecx as scratch and leaves addr_reg
1010  // unchanged.
1011  inline void GetMarkBits(Register addr_reg,
1012  Register bitmap_reg,
1013  Register mask_reg);
1014 
1015  // Helper for throwing exceptions. Compute a handler address and jump to
1016  // it. See the implementation for register usage.
1018 
1019  // Compute memory operands for safepoint stack slots.
1021  static int SafepointRegisterStackIndex(int reg_code);
1022 
1023  // Needs access to SafepointRegisterStackIndex for compiled frame
1024  // traversal.
1025  friend class StandardFrame;
1026 };
1027 
1028 
1029 // The code patcher is used to patch (typically) small parts of code e.g. for
1030 // debugging and other types of instrumentation. When using the code patcher
1031 // the exact number of bytes specified must be emitted. Is not legal to emit
1032 // relocation information. If any of these constraints are violated it causes
1033 // an assertion.
1034 class CodePatcher {
1035  public:
1036  CodePatcher(byte* address, int size);
1037  virtual ~CodePatcher();
1038 
1039  // Macro assembler to emit code.
1040  MacroAssembler* masm() { return &masm_; }
1041 
1042  private:
1043  byte* address_; // The address of the code being patched.
1044  int size_; // Number of bytes of the expected patch size.
1045  MacroAssembler masm_; // Macro assembler used to generate the code.
1046 };
1047 
1048 
1049 // -----------------------------------------------------------------------------
1050 // Static helper functions.
1051 
1052 // Generate an Operand for loading a field from an object.
1053 inline Operand FieldOperand(Register object, int offset) {
1054  return Operand(object, offset - kHeapObjectTag);
1055 }
1056 
1057 
1058 // Generate an Operand for loading an indexed field from an object.
1060  Register index,
1061  ScaleFactor scale,
1062  int offset) {
1063  return Operand(object, index, scale, offset - kHeapObjectTag);
1064 }
1065 
1066 
1068  Register index_as_smi,
1069  int additional_offset = 0) {
1070  int offset = FixedArray::kHeaderSize + additional_offset * kPointerSize;
1071  return FieldOperand(array, index_as_smi, times_half_pointer_size, offset);
1072 }
1073 
1074 
1075 inline Operand ContextOperand(Register context, int index) {
1076  return Operand(context, Context::SlotOffset(index));
1077 }
1078 
1079 
1080 inline Operand GlobalObjectOperand() {
1082 }
1083 
1084 
1085 // Generates an Operand for saving parameters after PrepareCallApiFunction.
1087 
1088 
1089 #ifdef GENERATED_CODE_COVERAGE
1090 extern void LogGeneratedCodeCoverage(const char* file_line);
1091 #define CODE_COVERAGE_STRINGIFY(x) #x
1092 #define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
1093 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
1094 #define ACCESS_MASM(masm) { \
1095  byte* ia32_coverage_function = \
1096  reinterpret_cast<byte*>(FUNCTION_ADDR(LogGeneratedCodeCoverage)); \
1097  masm->pushfd(); \
1098  masm->pushad(); \
1099  masm->push(Immediate(reinterpret_cast<int>(&__FILE_LINE__))); \
1100  masm->call(ia32_coverage_function, RelocInfo::RUNTIME_ENTRY); \
1101  masm->pop(eax); \
1102  masm->popad(); \
1103  masm->popfd(); \
1104  } \
1105  masm->
1106 #else
1107 #define ACCESS_MASM(masm) masm->
1108 #endif
1109 
1110 
1111 } } // namespace v8::internal
1112 
1113 #endif // V8_IA32_MACRO_ASSEMBLER_IA32_H_
Isolate * isolate() const
Definition: assembler.h:62
void and_(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
void sar(Register dst, uint8_t imm8)
void j(Condition cc, Label *L, Label::Distance distance=Label::kFar)
void add(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
void cmp(Register src1, const Operand &src2, Condition cond=al)
void shl(Register dst, uint8_t imm8)
void shift(Register dst, Immediate shift_amount, int subcode, int size)
void test(Register reg, const Immediate &imm)
CodePatcher(byte *address, int size)
static int SlotOffset(int index)
Definition: contexts.h:552
static const int kHeaderSize
Definition: objects.h:2393
static const int kValueOffset
Definition: objects.h:1506
void DecrementCounter(Condition cc, StatsCounter *counter, int value)
void CallStub(CodeStub *stub, TypeFeedbackId ast_id=TypeFeedbackId::None())
void Move(Register target, Register source)
void JumpIfNotUniqueNameInstanceType(Operand operand, Label *not_unique_name, Label::Distance distance=Label::kFar)
void JumpIfNotUniqueNameInstanceType(Register reg, Label *not_unique_name, Label::Distance distance=Label::kFar)
void CallApiFunctionAndReturn(Register function_address, ExternalReference thunk_ref, Operand thunk_last_arg, int stack_space, Operand return_value_operand, Operand *context_restore_operand)
void LoadAllocationTopHelper(Register result, Register scratch, AllocationFlags flags)
void NegativeZeroTest(Register result, Register op1, Register op2, Register scratch, Label *then_label)
void IncrementCounter(StatsCounter *counter, int value)
void RecordWriteField(Register object, int offset, Register value, Register scratch, SaveFPRegsMode save_fp, RememberedSetAction remembered_set_action=EMIT_REMEMBERED_SET, SmiCheck smi_check=INLINE_SMI_CHECK, PointersToHereCheck pointers_to_here_check_for_value=kPointersToHereMaybeInteresting)
void UpdateAllocationTopHelper(Register result_end, Register scratch, AllocationFlags flags)
void JumpIfSmi(Operand value, Label *smi_label, Label::Distance distance=Label::kFar)
void PushTryHandler(StackHandler::Kind kind, int handler_index)
void CheckFastSmiElements(Register map, Label *fail, Label::Distance distance=Label::kFar)
Operand SafepointRegisterSlot(Register reg)
void LoadObject(Register result, Handle< Object > object)
void AllocateOneByteSlicedString(Register result, Register scratch1, Register scratch2, Label *gc_required)
void EnterExitFrameEpilogue(int argc, bool save_doubles)
void EnsureNotWhite(Register object, Register scratch1, Register scratch2, Label *object_is_white_and_not_data, Label::Distance distance)
void CallCFunction(ExternalReference function, int num_arguments)
void AssertName(Register object)
void LeaveExitFrame(bool save_doubles)
void InvokeFunction(Handle< JSFunction > function, const ParameterCount &expected, const ParameterCount &actual, InvokeFlag flag, const CallWrapper &call_wrapper)
void PrepareCallCFunction(int num_arguments, Register scratch)
void AllocateOneByteString(Register result, Register length, Register scratch1, Register scratch2, Register scratch3, Label *gc_required)
void EnterFrame(StackFrame::Type type)
void LoadContext(Register dst, int context_chain_length)
void LoadTransitionedArrayMapConditional(ElementsKind expected_kind, ElementsKind transitioned_kind, Register map_in_out, Register scratch, Label *no_map_match)
void LoadRoot(Register destination, Heap::RootListIndex index)
void InitializeFieldsWithFiller(Register start_offset, Register end_offset, Register filler)
void ClampDoubleToUint8(XMMRegister input_reg, XMMRegister scratch_reg, Register result_reg)
void CallRuntime(Runtime::FunctionId id, int num_arguments, SaveFPRegsMode save_doubles=kDontSaveFPRegs)
void LoadHeapObject(Register dst, Handle< HeapObject > object)
void JumpIfNotUniqueNameInstanceType(Register reg, Label *not_unique_name)
void CallRuntime(const Runtime::Function *f, int num_arguments, SaveFPRegsMode save_doubles=kDontSaveFPRegs)
void CompareMap(Register obj, Handle< Map > map)
void AssertNumber(Register object)
void InvokeFunction(Register function, const ParameterCount &expected, const ParameterCount &actual, InvokeFlag flag, const CallWrapper &call_wrapper)
void CheckPageFlagForMap(Handle< Map > map, int mask, Condition cc, Label *condition_met, Label::Distance condition_met_distance=Label::kFar)
void RecordWriteField(Register object, int offset, Register value, Register scratch, LinkRegisterStatus lr_status, SaveFPRegsMode save_fp, RememberedSetAction remembered_set_action=EMIT_REMEMBERED_SET, SmiCheck smi_check=INLINE_SMI_CHECK, PointersToHereCheck pointers_to_here_check_for_value=kPointersToHereMaybeInteresting)
void AllocateHeapNumber(Register result, Register scratch1, Register scratch2, Label *gc_required, MutableMode mode=IMMUTABLE)
void InNewSpace(Register object, Register scratch, Condition cond, Label *branch)
void SafePush(const Immediate &x)
void CompareRoot(Register with, Heap::RootListIndex index)
void RecordWriteArray(Register array, Register value, Register index, SaveFPRegsMode save_fp, RememberedSetAction remembered_set_action=EMIT_REMEMBERED_SET, SmiCheck smi_check=INLINE_SMI_CHECK, PointersToHereCheck pointers_to_here_check_for_value=kPointersToHereMaybeInteresting)
void JumpToExternalReference(const ExternalReference &ext)
void CheckMapDeprecated(Handle< Map > map, Register scratch, Label *if_deprecated)
void CheckMap(Register obj, Handle< Map > map, Label *fail, SmiCheckType smi_check_type)
void BooleanBitTest(Register object, int field_offset, int bit_index)
void TryGetFunctionPrototype(Register function, Register result, Register scratch, Label *miss, bool miss_on_bound_function=false)
void AllocateTwoByteString(Register result, Register length, Register scratch1, Register scratch2, Register scratch3, Label *gc_required)
void InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag, const CallWrapper &call_wrapper=NullCallWrapper())
void JumpIfInstanceTypeIsNotSequentialOneByte(Register instance_type, Register scratch, Label *on_not_flat_one_byte_string)
void EnumLength(Register dst, Register map)
void TailCallStub(CodeStub *stub)
void EnterApiExitFrame(int argc)
void CheckPageFlag(Register object, Register scratch, int mask, Condition cc, Label *condition_met, Label::Distance condition_met_distance=Label::kFar)
void InvokePrologue(const ParameterCount &expected, const ParameterCount &actual, Handle< Code > code_constant, const Operand &code_operand, Label *done, bool *definitely_mismatches, InvokeFlag flag, Label::Distance done_distance, const CallWrapper &call_wrapper=NullCallWrapper())
static int SafepointRegisterStackIndex(int reg_code)
void StoreRoot(Register source, Register scratch, Heap::RootListIndex index)
STATIC_ASSERT((reg_zero==(reg_not_zero ^ 1)) &&(reg_bit_clear==(reg_bit_set ^ 1)) &&(always==(never ^ 1)))
void CopyBytes(Register source, Register destination, Register length, Register scratch)
void CompareRoot(const Operand &with, Heap::RootListIndex index)
void Throw(Register value)
void NegativeZeroTest(Register result, Register op, Label *then_label)
void StoreToSafepointRegisterSlot(Register dst, Immediate src)
void Move(Register dst, Handle< Object > value)
void IsInstanceJSObjectType(Register map, Register scratch, Label *fail)
void AssertString(Register object)
void AssertFastElements(Register elements)
void SmiUntag(Register reg, Label *is_smi)
bool AllowThisStubCall(CodeStub *stub)
void JumpIfNotSmi(Register value, Label *not_smi_label, Label::Distance distance=Label::kFar)
void Allocate(Register object_size, Register result, Register result_end, Register scratch, Label *gc_required, AllocationFlags flags)
void JumpIfNotInNewSpace(Register object, Register scratch, Label *branch, Label::Distance distance=Label::kFar)
void LoadFromNumberDictionary(Label *miss, Register elements, Register key, Register r0, Register r1, Register r2, Register result)
void CmpObjectType(Register heap_object, InstanceType type, Register map)
void CheckAccessGlobalProxy(Register holder_reg, Register scratch1, Register scratch2, Label *miss)
void IndexFromHash(Register hash, Register index)
void GetBuiltinFunction(Register target, Builtins::JavaScript id)
void Abort(BailoutReason reason)
void LeaveFrame(StackFrame::Type type)
void ClampUint8(Register reg)
void SafeMove(Register dst, const Immediate &x)
void TruncatingDiv(Register dividend, int32_t divisor)
void CheckFastElements(Register map, Label *fail, Label::Distance distance=Label::kFar)
void DispatchMap(Register obj, Register unused, Handle< Map > map, Handle< Code > success, SmiCheckType smi_check_type)
void TailCallExternalReference(const ExternalReference &ext, int num_arguments, int result_size)
void Allocate(int object_size, Register result, Register result_end, Register scratch, Label *gc_required, AllocationFlags flags)
void InvokeFunction(Register function, const ParameterCount &actual, InvokeFlag flag, const CallWrapper &call_wrapper)
void RecordWriteContextSlot(Register context, int offset, Register value, Register scratch, SaveFPRegsMode save_fp, RememberedSetAction remembered_set_action=EMIT_REMEMBERED_SET, SmiCheck smi_check=INLINE_SMI_CHECK, PointersToHereCheck pointers_to_here_check_for_value=kPointersToHereMaybeInteresting)
void InNewSpace(Register object, Register scratch, Condition cc, Label *condition_met, Label::Distance condition_met_distance=Label::kFar)
void AllocateTwoByteSlicedString(Register result, Register scratch1, Register scratch2, Label *gc_required)
void CompareRoot(Register with, Register scratch, Heap::RootListIndex index)
void Cvtsi2sd(XMMRegister dst, Register src)
void EmitSeqStringSetCharCheck(Register string, Register index, Register value, uint32_t encoding_mask)
void InvokeCode(Register code, const ParameterCount &expected, const ParameterCount &actual, InvokeFlag flag, const CallWrapper &call_wrapper)
void CmpHeapObject(Register reg, Handle< HeapObject > object)
void TruncateDoubleToI(Register result_reg, XMMRegister input_reg)
void DoubleToI(Register result_reg, XMMRegister input_reg, XMMRegister scratch, MinusZeroMode minus_zero_mode, Label *lost_precision, Label *is_nan, Label *minus_zero, Label::Distance dst=Label::kFar)
void JumpIfBlack(Register object, Register scratch0, Register scratch1, Label *on_black, Label::Distance on_black_distance=Label::kFar)
void LoadInstanceDescriptors(Register map, Register descriptors)
void HasColor(Register object, Register scratch0, Register scratch1, Label *has_color, Label::Distance has_color_distance, int first_bit, int second_bit)
void Ret(int bytes_dropped, Register scratch)
void JumpIfSmi(Register value, Label *smi_label, Label::Distance distance=Label::kFar)
void CheckEnumCache(Label *call_runtime)
void CallCFunction(Register function, int num_arguments)
void CmpInstanceType(Register map, InstanceType type)
void GetNumberHash(Register r0, Register scratch)
void TailCallRuntime(Runtime::FunctionId fid, int num_arguments, int result_size)
void EnterExitFrame(bool save_doubles)
void CallExternalReference(ExternalReference ref, int num_arguments)
void LeaveExitFrameEpilogue(bool restore_context)
void LoadPowerOf2(XMMRegister dst, Register scratch, int power)
void Move(XMMRegister dst, double val)
void AllocateTwoByteConsString(Register result, Register scratch1, Register scratch2, Label *gc_required)
void JumpIfInNewSpace(Register object, Register scratch, Label *branch, Label::Distance distance=Label::kFar)
void LeaveApiExitFrame(bool restore_context)
void RecordWriteForMap(Register object, Handle< Map > map, Register scratch1, Register scratch2, SaveFPRegsMode save_fp)
void Prologue(bool code_pre_aging)
void GetMarkBits(Register addr_reg, Register bitmap_reg, Register mask_reg)
void TruncateHeapNumberToI(Register result_reg, Register input_reg)
void UndoAllocationInNewSpace(Register object)
void InvokeCode(const Operand &code, const ParameterCount &expected, const ParameterCount &actual, InvokeFlag flag, const CallWrapper &call_wrapper)
void Drop(int element_count)
Condition IsObjectNameType(Register heap_object, Register map, Register instance_type)
void Store(Register src, const Operand &dst, Representation r)
void DecrementCounter(StatsCounter *counter, int value)
void Cvtsi2sd(XMMRegister dst, const Operand &src)
MacroAssembler(Isolate *isolate, void *buffer, int size)
void Allocate(int header_size, ScaleFactor element_size, Register element_count, RegisterValueType element_count_type, Register result, Register result_end, Register scratch, Label *gc_required, AllocationFlags flags)
void LoadFromSafepointRegisterSlot(Register dst, Register src)
void CmpObject(Register reg, Handle< Object > object)
void IsObjectJSObjectType(Register heap_object, Register map, Register scratch, Label *fail)
void StoreNumberToDoubleElements(Register maybe_number, Register elements, Register key, Register scratch1, XMMRegister scratch2, Label *fail, int offset=0)
void LookupNumberStringCache(Register object, Register result, Register scratch1, Register scratch2, Label *not_found)
void IncrementCounter(Condition cc, StatsCounter *counter, int value)
void LoadGlobalFunction(int index, Register function)
void AssertSmi(Register object)
void PushHeapObject(Handle< HeapObject > object)
void AllocateOneByteConsString(Register result, Register scratch1, Register scratch2, Label *gc_required)
void SetCounter(StatsCounter *counter, int value)
void LoadHeapObject(Register result, Handle< HeapObject > object)
void RecordWrite(Register object, Register address, Register value, SaveFPRegsMode save_fp, RememberedSetAction remembered_set_action=EMIT_REMEMBERED_SET, SmiCheck smi_check=INLINE_SMI_CHECK, PointersToHereCheck pointers_to_here_check_for_value=kPointersToHereMaybeInteresting)
void Load(Register dst, const Operand &src, Representation r)
void AssertUndefinedOrAllocationSite(Register object)
void JumpIfNotBothSequentialOneByteStrings(Register object1, Register object2, Register scratch1, Register scratch2, Label *on_not_flat_one_byte_strings)
void CheckFastObjectElements(Register map, Label *fail, Label::Distance distance=Label::kFar)
void ThrowUncatchable(Register value)
void RememberedSetHelper(Register object, Register addr, Register scratch, SaveFPRegsMode save_fp, RememberedSetFinalAction and_then)
void GetBuiltinEntry(Register target, Builtins::JavaScript id)
void TestJSArrayForAllocationMemento(Register receiver_reg, Register scratch_reg, Label *no_memento_found)
void JumpIfJSArrayHasAllocationMemento(Register receiver_reg, Register scratch_reg, Label *memento_found)
void Move(Register dst, const Immediate &x)
void Move(const Operand &dst, const Immediate &x)
void Assert(Condition cc, BailoutReason reason)
void StoreToSafepointRegisterSlot(Register dst, Register src)
void LoadUint32(XMMRegister dst, Register src)
void NumberOfOwnDescriptors(Register dst, Register map)
void PrepareCallApiFunction(int argc)
bool IsUnsafeImmediate(const Immediate &x)
void AllocateOneByteString(Register result, int length, Register scratch1, Register scratch2, Label *gc_required)
Condition IsObjectStringType(Register heap_object, Register map, Register instance_type)
void Check(Condition cc, BailoutReason reason)
void JumpIfDictionaryInPrototypeChain(Register object, Register scratch0, Register scratch1, Label *found)
void AssertNotSmi(Register object)
static int SafepointRegisterStackIndex(Register reg)
void LoadGlobalFunctionInitialMap(Register function, Register map)
void SlowTruncateToI(Register result_reg, Register input_reg, int offset=HeapNumber::kValueOffset - kHeapObjectTag)
void CallRuntimeSaveDoubles(Runtime::FunctionId id)
void Push(Handle< Object > handle)
static const Function * FunctionForId(FunctionId id)
Definition: runtime.cc:9312
static TypeFeedbackId None()
Definition: utils.h:945
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf map
enable harmony numeric enable harmony object literal extensions Optimize object size
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_BOOL(enable_always_align_csp
#define DCHECK(condition)
Definition: logging.h:205
InvokeFlag
AllocationFlags
int int32_t
Definition: unicode.cc:24
const int kPointerSize
Definition: globals.h:129
MemOperand ContextOperand(Register context, int index)
const Register r2
bool AreAliased(const CPURegister &reg1, const CPURegister &reg2, const CPURegister &reg3=NoReg, const CPURegister &reg4=NoReg, const CPURegister &reg5=NoReg, const CPURegister &reg6=NoReg, const CPURegister &reg7=NoReg, const CPURegister &reg8=NoReg)
TypeImpl< ZoneTypeConfig > Type
const Register r0
const int kSmiTagSize
Definition: v8.h:5743
Operand FieldOperand(Register object, int offset)
Handle< T > handle(T *t, Isolate *isolate)
Definition: handles.h:146
const Register esi
const Register r1
const int kHeapObjectTag
Definition: v8.h:5737
Operand FixedArrayElementOperand(Register array, Register index_as_smi, int additional_offset=0)
const Register no_reg
kFeedbackVectorOffset flag
Definition: objects-inl.h:5418
MemOperand GlobalObjectOperand()
const intptr_t kSmiTagMask
Definition: v8.h:5744
Operand ApiParameterOperand(int index)
const int kSmiTag
Definition: v8.h:5742
@ kPointersToHereAreAlwaysInteresting
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20