V8 Project
macro-assembler-x87.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_X87_MACRO_ASSEMBLER_X87_H_
6 #define V8_X87_MACRO_ASSEMBLER_X87_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.
18 typedef Operand MemOperand;
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, Register scratch,
79  SaveFPRegsMode save_fp,
80  RememberedSetFinalAction and_then);
81 
82  void CheckPageFlag(Register object,
83  Register scratch,
84  int mask,
85  Condition cc,
86  Label* condition_met,
87  Label::Distance condition_met_distance = Label::kFar);
88 
91  int mask,
92  Condition cc,
93  Label* condition_met,
94  Label::Distance condition_met_distance = Label::kFar);
95 
97  Register scratch,
98  Label* if_deprecated);
99 
100  // Check if object is in new space. Jumps if the object is not in new space.
101  // The register scratch can be object itself, but scratch will be clobbered.
103  Register scratch,
104  Label* branch,
105  Label::Distance distance = Label::kFar) {
106  InNewSpace(object, scratch, zero, branch, distance);
107  }
108 
109  // Check if object is in new space. Jumps if the object is in new space.
110  // The register scratch can be object itself, but it will be clobbered.
112  Register scratch,
113  Label* branch,
114  Label::Distance distance = Label::kFar) {
115  InNewSpace(object, scratch, not_zero, branch, distance);
116  }
117 
118  // Check if an object has a given incremental marking color. Also uses ecx!
119  void HasColor(Register object,
120  Register scratch0,
121  Register scratch1,
122  Label* has_color,
123  Label::Distance has_color_distance,
124  int first_bit,
125  int second_bit);
126 
127  void JumpIfBlack(Register object,
128  Register scratch0,
129  Register scratch1,
130  Label* on_black,
131  Label::Distance on_black_distance = Label::kFar);
132 
133  // Checks the color of an object. If the object is already grey or black
134  // then we just fall through, since it is already live. If it is white and
135  // we can determine that it doesn't need to be scanned, then we just mark it
136  // black and fall through. For the rest we jump to the label so the
137  // incremental marker can fix its assumptions.
139  Register scratch1,
140  Register scratch2,
141  Label* object_is_white_and_not_data,
142  Label::Distance distance);
143 
144  // Notify the garbage collector that we wrote a pointer into an object.
145  // |object| is the object being stored into, |value| is the object being
146  // stored. value and scratch registers are clobbered by the operation.
147  // The offset is the offset from the start of the object, not the offset from
148  // the tagged HeapObject pointer. For use with FieldOperand(reg, off).
150  Register object, int offset, Register value, Register scratch,
151  SaveFPRegsMode save_fp,
152  RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
153  SmiCheck smi_check = INLINE_SMI_CHECK,
154  PointersToHereCheck pointers_to_here_check_for_value =
156 
157  // As above, but the offset has the tag presubtracted. For use with
158  // Operand(reg, off).
160  Register context, int offset, Register value, Register scratch,
161  SaveFPRegsMode save_fp,
162  RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
163  SmiCheck smi_check = INLINE_SMI_CHECK,
164  PointersToHereCheck pointers_to_here_check_for_value =
166  RecordWriteField(context, offset + kHeapObjectTag, value, scratch, save_fp,
167  remembered_set_action, smi_check,
168  pointers_to_here_check_for_value);
169  }
170 
171  // Notify the garbage collector that we wrote a pointer into a fixed array.
172  // |array| is the array being stored into, |value| is the
173  // object being stored. |index| is the array index represented as a
174  // Smi. All registers are clobbered by the operation RecordWriteArray
175  // filters out smis so it does not update the write barrier if the
176  // value is a smi.
178  Register array, Register value, Register index, SaveFPRegsMode save_fp,
179  RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
180  SmiCheck smi_check = INLINE_SMI_CHECK,
181  PointersToHereCheck pointers_to_here_check_for_value =
183 
184  // For page containing |object| mark region covering |address|
185  // dirty. |object| is the object being stored into, |value| is the
186  // object being stored. The address and value registers are clobbered by the
187  // operation. RecordWrite filters out smis so it does not update the
188  // write barrier if the value is a smi.
190  Register object, Register address, Register value, SaveFPRegsMode save_fp,
191  RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
192  SmiCheck smi_check = INLINE_SMI_CHECK,
193  PointersToHereCheck pointers_to_here_check_for_value =
195 
196  // For page containing |object| mark the region covering the object's map
197  // dirty. |object| is the object being stored into, |map| is the Map object
198  // that was stored.
200  Register scratch2, SaveFPRegsMode save_fp);
201 
202  // ---------------------------------------------------------------------------
203  // Debugger Support
204 
205  void DebugBreak();
206 
207  // Generates function and stub prologue code.
208  void StubPrologue();
209  void Prologue(bool code_pre_aging);
210 
211  // Enter specific kind of exit frame. Expects the number of
212  // arguments in register eax and sets up the number of arguments in
213  // register edi and the pointer to the first argument in register
214  // esi.
215  void EnterExitFrame(bool save_doubles);
216 
217  void EnterApiExitFrame(int argc);
218 
219  // Leave the current exit frame. Expects the return value in
220  // register eax:edx (untouched) and the pointer to the first
221  // argument in register esi.
222  void LeaveExitFrame(bool save_doubles);
223 
224  // Leave the current exit frame. Expects the return value in
225  // register eax (untouched).
226  void LeaveApiExitFrame(bool restore_context);
227 
228  // Find the function context up the context chain.
229  void LoadContext(Register dst, int context_chain_length);
230 
231  // Conditionally load the cached Array transitioned map of type
232  // transitioned_kind from the native context if the map in register
233  // map_in_out is the cached Array map in the native context of
234  // expected_kind.
236  ElementsKind expected_kind,
237  ElementsKind transitioned_kind,
238  Register map_in_out,
239  Register scratch,
240  Label* no_map_match);
241 
242  // Load the global function with the given index.
243  void LoadGlobalFunction(int index, Register function);
244 
245  // Load the initial map from the global function. The registers
246  // function and map can be the same.
248 
249  // Push and pop the registers that can hold pointers.
252  // Store the value in register/immediate src in the safepoint
253  // register stack slot for register dst.
257 
261 
262  void LoadObject(Register result, Handle<Object> object) {
263  AllowDeferredHandleDereference heap_object_check;
264  if (object->IsHeapObject()) {
265  LoadHeapObject(result, Handle<HeapObject>::cast(object));
266  } else {
267  Move(result, Immediate(object));
268  }
269  }
270 
271  void CmpObject(Register reg, Handle<Object> object) {
272  AllowDeferredHandleDereference heap_object_check;
273  if (object->IsHeapObject()) {
275  } else {
276  cmp(reg, Immediate(object));
277  }
278  }
279 
280  // ---------------------------------------------------------------------------
281  // JavaScript invokes
282 
283  // Invoke the JavaScript function code by either calling or jumping.
284  void InvokeCode(Register code,
285  const ParameterCount& expected,
286  const ParameterCount& actual,
288  const CallWrapper& call_wrapper) {
289  InvokeCode(Operand(code), expected, actual, flag, call_wrapper);
290  }
291 
292  void InvokeCode(const Operand& code,
293  const ParameterCount& expected,
294  const ParameterCount& actual,
296  const CallWrapper& call_wrapper);
297 
298  // Invoke the JavaScript function in the given register. Changes the
299  // current context to the context in the function before invoking.
300  void InvokeFunction(Register function,
301  const ParameterCount& actual,
303  const CallWrapper& call_wrapper);
304 
305  void InvokeFunction(Register function,
306  const ParameterCount& expected,
307  const ParameterCount& actual,
309  const CallWrapper& call_wrapper);
310 
312  const ParameterCount& expected,
313  const ParameterCount& actual,
315  const CallWrapper& call_wrapper);
316 
317  // Invoke specified builtin JavaScript function. Adds an entry to
318  // the unresolved list if the name does not resolve.
321  const CallWrapper& call_wrapper = NullCallWrapper());
322 
323  // Store the function for the given builtin in the target register.
325 
326  // Store the code object for the given builtin in the target register.
328 
329  // Expression support
330  // Support for constant splitting.
331  bool IsUnsafeImmediate(const Immediate& x);
332  void SafeMove(Register dst, const Immediate& x);
333  void SafePush(const Immediate& x);
334 
335  // Compare object type for heap object.
336  // Incoming register is heap_object and outgoing register is map.
337  void CmpObjectType(Register heap_object, InstanceType type, Register map);
338 
339  // Compare instance type for map.
341 
342  // Check if a map for a JSObject indicates that the object has fast elements.
343  // Jump to the specified label if it does not.
345  Label* fail,
346  Label::Distance distance = Label::kFar);
347 
348  // Check if a map for a JSObject indicates that the object can have both smi
349  // and HeapObject elements. Jump to the specified label if it does not.
351  Label* fail,
352  Label::Distance distance = Label::kFar);
353 
354  // Check if a map for a JSObject indicates that the object has fast smi only
355  // elements. Jump to the specified label if it does not.
357  Label* fail,
358  Label::Distance distance = Label::kFar);
359 
360  // Check to see if maybe_number can be stored as a double in
361  // FastDoubleElements. If it can, store it at the index specified by key in
362  // the FastDoubleElements array elements, otherwise jump to fail.
364  Register elements,
365  Register key,
366  Register scratch,
367  Label* fail,
368  int offset = 0);
369 
370  // Compare an object's map with the specified map.
372 
373  // Check if the map of an object is equal to a specified map and branch to
374  // label if not. Skip the smi check if not required (object is known to be a
375  // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match
376  // against maps that are ElementsKind transition maps of the specified map.
377  void CheckMap(Register obj,
379  Label* fail,
380  SmiCheckType smi_check_type);
381 
382  // Check if the map of an object is equal to a specified map and branch to a
383  // specified target if equal. Skip the smi check if not required (object is
384  // known to be a heap object)
386  Register unused,
388  Handle<Code> success,
389  SmiCheckType smi_check_type);
390 
391  // Check if the object in register heap_object is a string. Afterwards the
392  // register map contains the object map and the register instance_type
393  // contains the instance_type. The registers map and instance_type can be the
394  // same in which case it contains the instance type afterwards. Either of the
395  // registers map and instance_type can be the same as heap_object.
397  Register map,
398  Register instance_type);
399 
400  // Check if the object in register heap_object is a name. Afterwards the
401  // register map contains the object map and the register instance_type
402  // contains the instance_type. The registers map and instance_type can be the
403  // same in which case it contains the instance type afterwards. Either of the
404  // registers map and instance_type can be the same as heap_object.
406  Register map,
407  Register instance_type);
408 
409  // Check if a heap object's type is in the JSObject range, not including
410  // JSFunction. The object's map will be loaded in the map register.
411  // Any or all of the three registers may be the same.
412  // The contents of the scratch register will always be overwritten.
413  void IsObjectJSObjectType(Register heap_object,
414  Register map,
415  Register scratch,
416  Label* fail);
417 
418  // The contents of the scratch register will be overwritten.
419  void IsInstanceJSObjectType(Register map, Register scratch, Label* fail);
420 
421  // FCmp is similar to integer cmp, but requires unsigned
422  // jcc instructions (je, ja, jae, jb, jbe, je, and jz).
423  void FCmp();
425  void FXamSign();
426  void X87CheckIA();
427  void X87SetRC(int rc);
428 
429  void ClampUint8(Register reg);
430  void ClampTOSToUint8(Register result_reg);
431 
432  void SlowTruncateToI(Register result_reg, Register input_reg,
434 
435  void TruncateHeapNumberToI(Register result_reg, Register input_reg);
436  void TruncateX87TOSToI(Register result_reg);
437 
438  void X87TOSToI(Register result_reg, MinusZeroMode minus_zero_mode,
439  Label* lost_precision, Label* is_nan, Label* minus_zero,
440  Label::Distance dst = Label::kFar);
441 
442  // Smi tagging support.
443  void SmiTag(Register reg) {
444  STATIC_ASSERT(kSmiTag == 0);
446  add(reg, reg);
447  }
448  void SmiUntag(Register reg) {
449  sar(reg, kSmiTagSize);
450  }
451 
452  // Modifies the register even if it does not contain a Smi!
453  void SmiUntag(Register reg, Label* is_smi) {
455  sar(reg, kSmiTagSize);
456  STATIC_ASSERT(kSmiTag == 0);
457  j(not_carry, is_smi);
458  }
459 
461 
462  // Jump the register contains a smi.
463  inline void JumpIfSmi(Register value,
464  Label* smi_label,
465  Label::Distance distance = Label::kFar) {
466  test(value, Immediate(kSmiTagMask));
467  j(zero, smi_label, distance);
468  }
469  // Jump if the operand is a smi.
470  inline void JumpIfSmi(Operand value,
471  Label* smi_label,
472  Label::Distance distance = Label::kFar) {
473  test(value, Immediate(kSmiTagMask));
474  j(zero, smi_label, distance);
475  }
476  // Jump if register contain a non-smi.
477  inline void JumpIfNotSmi(Register value,
478  Label* not_smi_label,
479  Label::Distance distance = Label::kFar) {
480  test(value, Immediate(kSmiTagMask));
481  j(not_zero, not_smi_label, distance);
482  }
483 
487 
488  template<typename Field>
489  void DecodeField(Register reg) {
490  static const int shift = Field::kShift;
491  static const int mask = Field::kMask >> Field::kShift;
492  if (shift != 0) {
493  sar(reg, shift);
494  }
495  and_(reg, Immediate(mask));
496  }
497 
498  template<typename Field>
500  static const int shift = Field::kShift;
501  static const int mask = (Field::kMask >> Field::kShift) << kSmiTagSize;
502  STATIC_ASSERT((mask & (0x80000000u >> (kSmiTagSize - 1))) == 0);
503  STATIC_ASSERT(kSmiTag == 0);
504  if (shift < kSmiTagSize) {
505  shl(reg, kSmiTagSize - shift);
506  } else if (shift > kSmiTagSize) {
507  sar(reg, shift - kSmiTagSize);
508  }
509  and_(reg, Immediate(mask));
510  }
511 
512  // Abort execution if argument is not a number, enabled via --debug-code.
513  void AssertNumber(Register object);
514 
515  // Abort execution if argument is not a smi, enabled via --debug-code.
516  void AssertSmi(Register object);
517 
518  // Abort execution if argument is a smi, enabled via --debug-code.
519  void AssertNotSmi(Register object);
520 
521  // Abort execution if argument is not a string, enabled via --debug-code.
522  void AssertString(Register object);
523 
524  // Abort execution if argument is not a name, enabled via --debug-code.
525  void AssertName(Register object);
526 
527  // Abort execution if argument is not undefined or an AllocationSite, enabled
528  // via --debug-code.
530 
531  // ---------------------------------------------------------------------------
532  // Exception handling
533 
534  // Push a new try handler and link it into try handler chain.
535  void PushTryHandler(StackHandler::Kind kind, int handler_index);
536 
537  // Unlink the stack handler on top of the stack from the try handler chain.
539 
540  // Throw to the top handler in the try hander chain.
541  void Throw(Register value);
542 
543  // Throw past all JS frames to the top JS entry frame.
545 
546  // ---------------------------------------------------------------------------
547  // Inline caching support
548 
549  // Generate code for checking access rights - used for security checks
550  // on access to global objects across environments. The holder register
551  // is left untouched, but the scratch register is clobbered.
553  Register scratch1,
554  Register scratch2,
555  Label* miss);
556 
558 
559  void LoadFromNumberDictionary(Label* miss,
560  Register elements,
561  Register key,
562  Register r0,
563  Register r1,
564  Register r2,
565  Register result);
566 
567 
568  // ---------------------------------------------------------------------------
569  // Allocation support
570 
571  // Allocate an object in new space or old pointer space. If the given space
572  // is exhausted control continues at the gc_required label. The allocated
573  // object is returned in result and end of the new object is returned in
574  // result_end. The register scratch can be passed as no_reg in which case
575  // an additional object reference will be added to the reloc info. The
576  // returned pointers in result and result_end have not yet been tagged as
577  // heap objects. If result_contains_top_on_entry is true the content of
578  // result is known to be the allocation top on entry (could be result_end
579  // from a previous call). If result_contains_top_on_entry is true scratch
580  // should be no_reg as it is never used.
581  void Allocate(int object_size,
582  Register result,
583  Register result_end,
584  Register scratch,
585  Label* gc_required,
587 
588  void Allocate(int header_size,
589  ScaleFactor element_size,
590  Register element_count,
591  RegisterValueType element_count_type,
592  Register result,
593  Register result_end,
594  Register scratch,
595  Label* gc_required,
597 
598  void Allocate(Register object_size,
599  Register result,
600  Register result_end,
601  Register scratch,
602  Label* gc_required,
604 
605  // Undo allocation in new space. The object passed and objects allocated after
606  // it will no longer be allocated. Make sure that no pointers are left to the
607  // object(s) no longer allocated as they would be invalid when allocation is
608  // un-done.
610 
611  // Allocate a heap number in new space with undefined value. The
612  // register scratch2 can be passed as no_reg; the others must be
613  // valid registers. Returns tagged pointer in result register, or
614  // jumps to gc_required if new space is full.
616  Register scratch1,
617  Register scratch2,
618  Label* gc_required,
620 
621  // Allocate a sequential string. All the header fields of the string object
622  // are initialized.
624  Register length,
625  Register scratch1,
626  Register scratch2,
627  Register scratch3,
628  Label* gc_required);
630  Register scratch1, Register scratch2,
631  Register scratch3, Label* gc_required);
632  void AllocateOneByteString(Register result, int length, Register scratch1,
633  Register scratch2, Label* gc_required);
634 
635  // Allocate a raw cons string object. Only the map field of the result is
636  // initialized.
638  Register scratch1,
639  Register scratch2,
640  Label* gc_required);
642  Register scratch2, Label* gc_required);
643 
644  // Allocate a raw sliced string object. Only the map field of the result is
645  // initialized.
647  Register scratch1,
648  Register scratch2,
649  Label* gc_required);
651  Register scratch2, Label* gc_required);
652 
653  // Copy memory, byte-by-byte, from source to destination. Not optimized for
654  // long or aligned copies.
655  // The contents of index and scratch are destroyed.
656  void CopyBytes(Register source,
657  Register destination,
658  Register length,
659  Register scratch);
660 
661  // Initialize fields with filler values. Fields starting at |start_offset|
662  // not including end_offset are overwritten with the value in |filler|. At
663  // the end the loop, |start_offset| takes the value of |end_offset|.
665  Register end_offset,
666  Register filler);
667 
668  // ---------------------------------------------------------------------------
669  // Support functions.
670 
671  // Check a boolean-bit of a Smi field.
672  void BooleanBitTest(Register object, int field_offset, int bit_index);
673 
674  // Check if result is zero and op is negative.
675  void NegativeZeroTest(Register result, Register op, Label* then_label);
676 
677  // Check if result is zero and any of op1 and op2 are negative.
678  // Register scratch is destroyed, and it must be different from op2.
680  Register scratch, Label* then_label);
681 
682  // Try to get function prototype of a function and puts the value in
683  // the result register. Checks that the function really is a
684  // function and jumps to the miss label if the fast checks fail. The
685  // function register will be untouched; the other registers may be
686  // clobbered.
688  Register result,
689  Register scratch,
690  Label* miss,
691  bool miss_on_bound_function = false);
692 
693  // Picks out an array index from the hash field.
694  // Register use:
695  // hash - holds the index's hash. Clobbered.
696  // index - holds the overwritten index on exit.
697  void IndexFromHash(Register hash, Register index);
698 
699  // ---------------------------------------------------------------------------
700  // Runtime calls
701 
702  // Call a code stub. Generate the code if necessary.
704 
705  // Tail call a code stub (jump). Generate the code if necessary.
706  void TailCallStub(CodeStub* stub);
707 
708  // Return from a code stub after popping its arguments.
709  void StubReturn(int argc);
710 
711  // Call a runtime routine.
712  void CallRuntime(const Runtime::Function* f, int num_arguments,
713  SaveFPRegsMode save_doubles = kDontSaveFPRegs);
715  const Runtime::Function* function = Runtime::FunctionForId(id);
716  CallRuntime(function, function->nargs, kSaveFPRegs);
717  }
718 
719  // Convenience function: Same as above, but takes the fid instead.
720  void CallRuntime(Runtime::FunctionId id, int num_arguments,
721  SaveFPRegsMode save_doubles = kDontSaveFPRegs) {
722  CallRuntime(Runtime::FunctionForId(id), num_arguments, save_doubles);
723  }
724 
725  // Convenience function: call an external reference.
726  void CallExternalReference(ExternalReference ref, int num_arguments);
727 
728  // Tail call of a runtime routine (jump).
729  // Like JumpToExternalReference, but also takes care of passing the number
730  // of parameters.
731  void TailCallExternalReference(const ExternalReference& ext,
732  int num_arguments,
733  int result_size);
734 
735  // Convenience function: tail call a runtime routine (jump).
737  int num_arguments,
738  int result_size);
739 
740  // Before calling a C-function from generated code, align arguments on stack.
741  // After aligning the frame, arguments must be stored in esp[0], esp[4],
742  // etc., not pushed. The argument count assumes all arguments are word sized.
743  // Some compilers/platforms require the stack to be aligned when calling
744  // C++ code.
745  // Needs a scratch register to do some arithmetic. This register will be
746  // trashed.
747  void PrepareCallCFunction(int num_arguments, Register scratch);
748 
749  // Calls a C function and cleans up the space for arguments allocated
750  // by PrepareCallCFunction. The called function is not allowed to trigger a
751  // garbage collection, since that might move the code and invalidate the
752  // return address (unless this is somehow accounted for by the called
753  // function).
754  void CallCFunction(ExternalReference function, int num_arguments);
755  void CallCFunction(Register function, int num_arguments);
756 
757  // Prepares stack to put arguments (aligns and so on). Reserves
758  // space for return value if needed (assumes the return value is a handle).
759  // Arguments must be stored in ApiParameterOperand(0), ApiParameterOperand(1)
760  // etc. Saves context (esi). If space was reserved for return value then
761  // stores the pointer to the reserved slot into esi.
762  void PrepareCallApiFunction(int argc);
763 
764  // Calls an API function. Allocates HandleScope, extracts returned value
765  // from handle and propagates exceptions. Clobbers ebx, edi and
766  // caller-save registers. Restores context. On return removes
767  // stack_space * kPointerSize (GCed).
768  void CallApiFunctionAndReturn(Register function_address,
769  ExternalReference thunk_ref,
770  Operand thunk_last_arg,
771  int stack_space,
772  Operand return_value_operand,
773  Operand* context_restore_operand);
774 
775  // Jump to a runtime routine.
776  void JumpToExternalReference(const ExternalReference& ext);
777 
778  // ---------------------------------------------------------------------------
779  // Utilities
780 
781  void Ret();
782 
783  // Return and drop arguments from stack, where the number of arguments
784  // may be bigger than 2^16 - 1. Requires a scratch register.
785  void Ret(int bytes_dropped, Register scratch);
786 
787  // Emit code to discard a non-negative number of pointer-sized elements
788  // from the stack, clobbering only the esp register.
789  void Drop(int element_count);
790 
791  void Call(Label* target) { call(target); }
792  void Push(Register src) { push(src); }
793  void Pop(Register dst) { pop(dst); }
794 
795  // Emit call to the code we are currently generating.
796  void CallSelf() {
797  Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location()));
799  }
800 
801  // Move if the registers are not identical.
802  void Move(Register target, Register source);
803 
804  // Move a constant into a destination using the most efficient encoding.
805  void Move(Register dst, const Immediate& x);
806  void Move(const Operand& dst, const Immediate& x);
807 
808  // Push a handle value.
810  void Push(Smi* smi) { Push(Handle<Smi>(smi, isolate())); }
811 
813  DCHECK(!code_object_.is_null());
814  return code_object_;
815  }
816 
817  // Insert code to verify that the x87 stack has the specified depth (0-7)
819 
820  // Emit code for a truncating division by a constant. The dividend register is
821  // unchanged, the result is in edx, and eax gets clobbered.
822  void TruncatingDiv(Register dividend, int32_t divisor);
823 
824  // ---------------------------------------------------------------------------
825  // StatsCounter support
826 
827  void SetCounter(StatsCounter* counter, int value);
828  void IncrementCounter(StatsCounter* counter, int value);
829  void DecrementCounter(StatsCounter* counter, int value);
830  void IncrementCounter(Condition cc, StatsCounter* counter, int value);
831  void DecrementCounter(Condition cc, StatsCounter* counter, int value);
832 
833 
834  // ---------------------------------------------------------------------------
835  // Debugging
836 
837  // Calls Abort(msg) if the condition cc is not satisfied.
838  // Use --debug_code to enable.
840 
841  void AssertFastElements(Register elements);
842 
843  // Like Assert(), but always enabled.
845 
846  // Print a message to stdout and abort execution.
847  void Abort(BailoutReason reason);
848 
849  // Check that the stack is aligned.
851 
852  // Verify restrictions about code generated in stubs.
853  void set_generating_stub(bool value) { generating_stub_ = value; }
855  void set_has_frame(bool value) { has_frame_ = value; }
856  bool has_frame() { return has_frame_; }
857  inline bool AllowThisStubCall(CodeStub* stub);
858 
859  // ---------------------------------------------------------------------------
860  // String utilities.
861 
862  // Generate code to do a lookup in the number string cache. If the number in
863  // the register object is found in the cache the generated code falls through
864  // with the result in the result register. The object and the result register
865  // can be the same. If the number is not found in the cache the code jumps to
866  // the label not_found with only the content of register object unchanged.
868  Register result,
869  Register scratch1,
870  Register scratch2,
871  Label* not_found);
872 
873  // Check whether the instance type represents a flat one-byte string. Jump to
874  // the label if not. If the instance type can be scratched specify same
875  // register for both instance type and scratch.
877  Register instance_type, Register scratch,
878  Label* on_not_flat_one_byte_string);
879 
880  // Checks if both objects are sequential one-byte strings, and jumps to label
881  // if either is not.
883  Register object1, Register object2, Register scratch1, Register scratch2,
884  Label* on_not_flat_one_byte_strings);
885 
886  // Checks if the given register or operand is a unique name
887  void JumpIfNotUniqueNameInstanceType(Register reg, Label* not_unique_name,
888  Label::Distance distance = Label::kFar) {
889  JumpIfNotUniqueNameInstanceType(Operand(reg), not_unique_name, distance);
890  }
891 
892  void JumpIfNotUniqueNameInstanceType(Operand operand, Label* not_unique_name,
893  Label::Distance distance = Label::kFar);
894 
896  Register index,
897  Register value,
898  uint32_t encoding_mask);
899 
901  return SafepointRegisterStackIndex(reg.code());
902  }
903 
904  // Activation support.
907 
908  // Expects object in eax and returns map with validated enum cache
909  // in eax. Assumes that any other register can be used as a scratch.
910  void CheckEnumCache(Label* call_runtime);
911 
912  // AllocationMemento support. Arrays may have an associated
913  // AllocationMemento object that can be checked for in order to pretransition
914  // to another type.
915  // On entry, receiver_reg should point to the array object.
916  // scratch_reg gets clobbered.
917  // If allocation info is present, conditional code is set to equal.
919  Register scratch_reg,
920  Label* no_memento_found);
921 
923  Register scratch_reg,
924  Label* memento_found) {
925  Label no_memento_found;
926  TestJSArrayForAllocationMemento(receiver_reg, scratch_reg,
927  &no_memento_found);
928  j(equal, memento_found);
929  bind(&no_memento_found);
930  }
931 
932  // Jumps to found label if a prototype map has dictionary elements.
934  Register scratch1, Label* found);
935 
936  private:
937  bool generating_stub_;
938  bool has_frame_;
939  // This handle will be patched with the code object on installation.
941 
942  // Helper functions for generating invokes.
943  void InvokePrologue(const ParameterCount& expected,
944  const ParameterCount& actual,
945  Handle<Code> code_constant,
946  const Operand& code_operand,
947  Label* done,
948  bool* definitely_mismatches,
950  Label::Distance done_distance,
951  const CallWrapper& call_wrapper = NullCallWrapper());
952 
954  void EnterExitFrameEpilogue(int argc, bool save_doubles);
955 
956  void LeaveExitFrameEpilogue(bool restore_context);
957 
958  // Allocation support helpers.
960  Register scratch,
962 
964  Register scratch,
966 
967  // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace.
968  void InNewSpace(Register object,
969  Register scratch,
970  Condition cc,
971  Label* condition_met,
972  Label::Distance condition_met_distance = Label::kFar);
973 
974  // Helper for finding the mark bits for an address. Afterwards, the
975  // bitmap register points at the word with the mark bits and the mask
976  // the position of the first bit. Uses ecx as scratch and leaves addr_reg
977  // unchanged.
978  inline void GetMarkBits(Register addr_reg,
979  Register bitmap_reg,
980  Register mask_reg);
981 
982  // Helper for throwing exceptions. Compute a handler address and jump to
983  // it. See the implementation for register usage.
985 
986  // Compute memory operands for safepoint stack slots.
988  static int SafepointRegisterStackIndex(int reg_code);
989 
990  // Needs access to SafepointRegisterStackIndex for compiled frame
991  // traversal.
992  friend class StandardFrame;
993 };
994 
995 
996 // The code patcher is used to patch (typically) small parts of code e.g. for
997 // debugging and other types of instrumentation. When using the code patcher
998 // the exact number of bytes specified must be emitted. Is not legal to emit
999 // relocation information. If any of these constraints are violated it causes
1000 // an assertion.
1001 class CodePatcher {
1002  public:
1003  CodePatcher(byte* address, int size);
1004  virtual ~CodePatcher();
1005 
1006  // Macro assembler to emit code.
1007  MacroAssembler* masm() { return &masm_; }
1008 
1009  private:
1010  byte* address_; // The address of the code being patched.
1011  int size_; // Number of bytes of the expected patch size.
1012  MacroAssembler masm_; // Macro assembler used to generate the code.
1013 };
1014 
1015 
1016 // -----------------------------------------------------------------------------
1017 // Static helper functions.
1018 
1019 // Generate an Operand for loading a field from an object.
1020 inline Operand FieldOperand(Register object, int offset) {
1021  return Operand(object, offset - kHeapObjectTag);
1022 }
1023 
1024 
1025 // Generate an Operand for loading an indexed field from an object.
1026 inline Operand FieldOperand(Register object,
1027  Register index,
1028  ScaleFactor scale,
1029  int offset) {
1030  return Operand(object, index, scale, offset - kHeapObjectTag);
1031 }
1032 
1033 
1034 inline Operand FixedArrayElementOperand(Register array,
1035  Register index_as_smi,
1036  int additional_offset = 0) {
1037  int offset = FixedArray::kHeaderSize + additional_offset * kPointerSize;
1038  return FieldOperand(array, index_as_smi, times_half_pointer_size, offset);
1039 }
1040 
1041 
1042 inline Operand ContextOperand(Register context, int index) {
1043  return Operand(context, Context::SlotOffset(index));
1044 }
1045 
1046 
1047 inline Operand GlobalObjectOperand() {
1049 }
1050 
1051 
1052 // Generates an Operand for saving parameters after PrepareCallApiFunction.
1053 Operand ApiParameterOperand(int index);
1054 
1055 
1056 #ifdef GENERATED_CODE_COVERAGE
1057 extern void LogGeneratedCodeCoverage(const char* file_line);
1058 #define CODE_COVERAGE_STRINGIFY(x) #x
1059 #define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
1060 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
1061 #define ACCESS_MASM(masm) { \
1062  byte* ia32_coverage_function = \
1063  reinterpret_cast<byte*>(FUNCTION_ADDR(LogGeneratedCodeCoverage)); \
1064  masm->pushfd(); \
1065  masm->pushad(); \
1066  masm->push(Immediate(reinterpret_cast<int>(&__FILE_LINE__))); \
1067  masm->call(ia32_coverage_function, RelocInfo::RUNTIME_ENTRY); \
1068  masm->pop(eax); \
1069  masm->popad(); \
1070  masm->popfd(); \
1071  } \
1072  masm->
1073 #else
1074 #define ACCESS_MASM(masm) masm->
1075 #endif
1076 
1077 
1078 } } // namespace v8::internal
1079 
1080 #endif // V8_X87_MACRO_ASSEMBLER_X87_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 ClampTOSToUint8(Register result_reg)
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 VerifyX87StackDepth(uint32_t depth)
void StoreNumberToDoubleElements(Register maybe_number, Register elements, Register key, Register scratch, Label *fail, int offset=0)
void LoadRoot(Register destination, Heap::RootListIndex index)
void InitializeFieldsWithFiller(Register start_offset, Register end_offset, Register filler)
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 TruncateX87TOSToI(Register result_reg)
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 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 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 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)
MacroAssembler(Isolate *isolate, void *buffer, int size)
void X87TOSToI(Register result_reg, MinusZeroMode minus_zero_mode, Label *lost_precision, Label *is_nan, Label *minus_zero, Label::Distance dst=Label::kFar)
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 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 LoadUint32NoSSE2(Register src)
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 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