v8  3.14.5(node0.10.28)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
code-stubs-arm.h
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #ifndef V8_ARM_CODE_STUBS_ARM_H_
29 #define V8_ARM_CODE_STUBS_ARM_H_
30 
31 #include "ic-inl.h"
32 
33 namespace v8 {
34 namespace internal {
35 
36 
37 // Compute a transcendental math function natively, or call the
38 // TranscendentalCache runtime function.
39 class TranscendentalCacheStub: public CodeStub {
40  public:
41  enum ArgumentType {
44  };
45 
47  ArgumentType argument_type)
48  : type_(type), argument_type_(argument_type) { }
49  void Generate(MacroAssembler* masm);
50  private:
52  ArgumentType argument_type_;
53  void GenerateCallCFunction(MacroAssembler* masm, Register scratch);
54 
55  Major MajorKey() { return TranscendentalCache; }
56  int MinorKey() { return type_ | argument_type_; }
57  Runtime::FunctionId RuntimeFunction();
58 };
59 
60 
61 class StoreBufferOverflowStub: public CodeStub {
62  public:
64  : save_doubles_(save_fp) { }
65 
66  void Generate(MacroAssembler* masm);
67 
68  virtual bool IsPregenerated();
70  virtual bool SometimesSetsUpAFrame() { return false; }
71 
72  private:
73  SaveFPRegsMode save_doubles_;
74 
75  Major MajorKey() { return StoreBufferOverflow; }
76  int MinorKey() { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; }
77 };
78 
79 
80 class UnaryOpStub: public CodeStub {
81  public:
83  UnaryOverwriteMode mode,
85  : op_(op),
86  mode_(mode),
87  operand_type_(operand_type) {
88  }
89 
90  private:
91  Token::Value op_;
92  UnaryOverwriteMode mode_;
93 
94  // Operand type information determined at runtime.
95  UnaryOpIC::TypeInfo operand_type_;
96 
97  virtual void PrintName(StringStream* stream);
98 
99  class ModeBits: public BitField<UnaryOverwriteMode, 0, 1> {};
100  class OpBits: public BitField<Token::Value, 1, 7> {};
101  class OperandTypeInfoBits: public BitField<UnaryOpIC::TypeInfo, 8, 3> {};
102 
103  Major MajorKey() { return UnaryOp; }
104  int MinorKey() {
105  return ModeBits::encode(mode_)
106  | OpBits::encode(op_)
107  | OperandTypeInfoBits::encode(operand_type_);
108  }
109 
110  // Note: A lot of the helper functions below will vanish when we use virtual
111  // function instead of switch more often.
112  void Generate(MacroAssembler* masm);
113 
114  void GenerateTypeTransition(MacroAssembler* masm);
115 
116  void GenerateSmiStub(MacroAssembler* masm);
117  void GenerateSmiStubSub(MacroAssembler* masm);
118  void GenerateSmiStubBitNot(MacroAssembler* masm);
119  void GenerateSmiCodeSub(MacroAssembler* masm, Label* non_smi, Label* slow);
120  void GenerateSmiCodeBitNot(MacroAssembler* masm, Label* slow);
121 
122  void GenerateHeapNumberStub(MacroAssembler* masm);
123  void GenerateHeapNumberStubSub(MacroAssembler* masm);
124  void GenerateHeapNumberStubBitNot(MacroAssembler* masm);
125  void GenerateHeapNumberCodeSub(MacroAssembler* masm, Label* slow);
126  void GenerateHeapNumberCodeBitNot(MacroAssembler* masm, Label* slow);
127 
128  void GenerateGenericStub(MacroAssembler* masm);
129  void GenerateGenericStubSub(MacroAssembler* masm);
130  void GenerateGenericStubBitNot(MacroAssembler* masm);
131  void GenerateGenericCodeFallback(MacroAssembler* masm);
132 
133  virtual int GetCodeKind() { return Code::UNARY_OP_IC; }
134 
135  virtual InlineCacheState GetICState() {
136  return UnaryOpIC::ToState(operand_type_);
137  }
138 
139  virtual void FinishCode(Handle<Code> code) {
140  code->set_unary_op_type(operand_type_);
141  }
142 };
143 
144 
145 class BinaryOpStub: public CodeStub {
146  public:
148  : op_(op),
149  mode_(mode),
150  operands_type_(BinaryOpIC::UNINITIALIZED),
151  result_type_(BinaryOpIC::UNINITIALIZED) {
152  use_vfp2_ = CpuFeatures::IsSupported(VFP2);
153  ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
154  }
155 
157  int key,
158  BinaryOpIC::TypeInfo operands_type,
160  : op_(OpBits::decode(key)),
161  mode_(ModeBits::decode(key)),
162  use_vfp2_(VFP2Bits::decode(key)),
163  operands_type_(operands_type),
164  result_type_(result_type) { }
165 
166  private:
167  enum SmiCodeGenerateHeapNumberResults {
168  ALLOW_HEAPNUMBER_RESULTS,
169  NO_HEAPNUMBER_RESULTS
170  };
171 
172  Token::Value op_;
173  OverwriteMode mode_;
174  bool use_vfp2_;
175 
176  // Operand type information determined at runtime.
177  BinaryOpIC::TypeInfo operands_type_;
178  BinaryOpIC::TypeInfo result_type_;
179 
180  virtual void PrintName(StringStream* stream);
181 
182  // Minor key encoding in 16 bits RRRTTTVOOOOOOOMM.
183  class ModeBits: public BitField<OverwriteMode, 0, 2> {};
184  class OpBits: public BitField<Token::Value, 2, 7> {};
185  class VFP2Bits: public BitField<bool, 9, 1> {};
186  class OperandTypeInfoBits: public BitField<BinaryOpIC::TypeInfo, 10, 3> {};
187  class ResultTypeInfoBits: public BitField<BinaryOpIC::TypeInfo, 13, 3> {};
188 
189  Major MajorKey() { return BinaryOp; }
190  int MinorKey() {
191  return OpBits::encode(op_)
192  | ModeBits::encode(mode_)
193  | VFP2Bits::encode(use_vfp2_)
194  | OperandTypeInfoBits::encode(operands_type_)
195  | ResultTypeInfoBits::encode(result_type_);
196  }
197 
198  void Generate(MacroAssembler* masm);
199  void GenerateGeneric(MacroAssembler* masm);
200  void GenerateSmiSmiOperation(MacroAssembler* masm);
201  void GenerateFPOperation(MacroAssembler* masm,
202  bool smi_operands,
203  Label* not_numbers,
204  Label* gc_required);
205  void GenerateSmiCode(MacroAssembler* masm,
206  Label* use_runtime,
207  Label* gc_required,
208  SmiCodeGenerateHeapNumberResults heapnumber_results);
209  void GenerateLoadArguments(MacroAssembler* masm);
210  void GenerateReturn(MacroAssembler* masm);
211  void GenerateUninitializedStub(MacroAssembler* masm);
212  void GenerateSmiStub(MacroAssembler* masm);
213  void GenerateInt32Stub(MacroAssembler* masm);
214  void GenerateHeapNumberStub(MacroAssembler* masm);
215  void GenerateOddballStub(MacroAssembler* masm);
216  void GenerateStringStub(MacroAssembler* masm);
217  void GenerateBothStringStub(MacroAssembler* masm);
218  void GenerateGenericStub(MacroAssembler* masm);
219  void GenerateAddStrings(MacroAssembler* masm);
220  void GenerateCallRuntime(MacroAssembler* masm);
221 
222  void GenerateHeapResultAllocation(MacroAssembler* masm,
223  Register result,
224  Register heap_number_map,
225  Register scratch1,
226  Register scratch2,
227  Label* gc_required);
228  void GenerateRegisterArgsPush(MacroAssembler* masm);
229  void GenerateTypeTransition(MacroAssembler* masm);
230  void GenerateTypeTransitionWithSavedArgs(MacroAssembler* masm);
231 
232  virtual int GetCodeKind() { return Code::BINARY_OP_IC; }
233 
234  virtual InlineCacheState GetICState() {
235  return BinaryOpIC::ToState(operands_type_);
236  }
237 
238  virtual void FinishCode(Handle<Code> code) {
239  code->set_binary_op_type(operands_type_);
240  code->set_binary_op_result_type(result_type_);
241  }
242 
243  friend class CodeGenerator;
244 };
245 
246 
247 class StringHelper : public AllStatic {
248  public:
249  // Generate code for copying characters using a simple loop. This should only
250  // be used in places where the number of characters is small and the
251  // additional setup and checking in GenerateCopyCharactersLong adds too much
252  // overhead. Copying of overlapping regions is not supported.
253  // Dest register ends at the position after the last character written.
254  static void GenerateCopyCharacters(MacroAssembler* masm,
255  Register dest,
256  Register src,
257  Register count,
258  Register scratch,
259  bool ascii);
260 
261  // Generate code for copying a large number of characters. This function
262  // is allowed to spend extra time setting up conditions to make copying
263  // faster. Copying of overlapping regions is not supported.
264  // Dest register ends at the position after the last character written.
265  static void GenerateCopyCharactersLong(MacroAssembler* masm,
266  Register dest,
267  Register src,
268  Register count,
269  Register scratch1,
270  Register scratch2,
271  Register scratch3,
272  Register scratch4,
273  Register scratch5,
274  int flags);
275 
276 
277  // Probe the symbol table for a two character string. If the string is
278  // not found by probing a jump to the label not_found is performed. This jump
279  // does not guarantee that the string is not in the symbol table. If the
280  // string is found the code falls through with the string in register r0.
281  // Contents of both c1 and c2 registers are modified. At the exit c1 is
282  // guaranteed to contain halfword with low and high bytes equal to
283  // initial contents of c1 and c2 respectively.
285  Register c1,
286  Register c2,
287  Register scratch1,
288  Register scratch2,
289  Register scratch3,
290  Register scratch4,
291  Register scratch5,
292  Label* not_found);
293 
294  // Generate string hash.
295  static void GenerateHashInit(MacroAssembler* masm,
296  Register hash,
297  Register character);
298 
299  static void GenerateHashAddCharacter(MacroAssembler* masm,
300  Register hash,
301  Register character);
302 
303  static void GenerateHashGetHash(MacroAssembler* masm,
304  Register hash);
305 
306  private:
307  DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper);
308 };
309 
310 
311 // Flag that indicates how to generate code for the stub StringAddStub.
314  // Omit left string check in stub (left is definitely a string).
316  // Omit right string check in stub (right is definitely a string).
318  // Omit both string checks in stub.
321 };
322 
323 
324 class StringAddStub: public CodeStub {
325  public:
326  explicit StringAddStub(StringAddFlags flags) : flags_(flags) {}
327 
328  private:
329  Major MajorKey() { return StringAdd; }
330  int MinorKey() { return flags_; }
331 
332  void Generate(MacroAssembler* masm);
333 
334  void GenerateConvertArgument(MacroAssembler* masm,
335  int stack_offset,
336  Register arg,
337  Register scratch1,
338  Register scratch2,
339  Register scratch3,
340  Register scratch4,
341  Label* slow);
342 
343  const StringAddFlags flags_;
344 };
345 
346 
347 class SubStringStub: public CodeStub {
348  public:
350 
351  private:
352  Major MajorKey() { return SubString; }
353  int MinorKey() { return 0; }
354 
355  void Generate(MacroAssembler* masm);
356 };
357 
358 
359 
360 class StringCompareStub: public CodeStub {
361  public:
363 
364  // Compares two flat ASCII strings and returns result in r0.
366  Register left,
367  Register right,
368  Register scratch1,
369  Register scratch2,
370  Register scratch3,
371  Register scratch4);
372 
373  // Compares two flat ASCII strings for equality and returns result
374  // in r0.
376  Register left,
377  Register right,
378  Register scratch1,
379  Register scratch2,
380  Register scratch3);
381 
382  private:
383  virtual Major MajorKey() { return StringCompare; }
384  virtual int MinorKey() { return 0; }
385  virtual void Generate(MacroAssembler* masm);
386 
387  static void GenerateAsciiCharsCompareLoop(MacroAssembler* masm,
388  Register left,
389  Register right,
390  Register length,
391  Register scratch1,
392  Register scratch2,
393  Label* chars_not_equal);
394 };
395 
396 
397 // This stub can convert a signed int32 to a heap number (double). It does
398 // not work for int32s that are in Smi range! No GC occurs during this stub
399 // so you don't have to set up the frame.
400 class WriteInt32ToHeapNumberStub : public CodeStub {
401  public:
403  Register the_heap_number,
404  Register scratch)
405  : the_int_(the_int),
406  the_heap_number_(the_heap_number),
407  scratch_(scratch) { }
408 
409  bool IsPregenerated();
410  static void GenerateFixedRegStubsAheadOfTime();
411 
412  private:
413  Register the_int_;
414  Register the_heap_number_;
415  Register scratch_;
416 
417  // Minor key encoding in 16 bits.
418  class IntRegisterBits: public BitField<int, 0, 4> {};
419  class HeapNumberRegisterBits: public BitField<int, 4, 4> {};
420  class ScratchRegisterBits: public BitField<int, 8, 4> {};
421 
422  Major MajorKey() { return WriteInt32ToHeapNumber; }
423  int MinorKey() {
424  // Encode the parameters in a unique 16 bit value.
425  return IntRegisterBits::encode(the_int_.code())
426  | HeapNumberRegisterBits::encode(the_heap_number_.code())
427  | ScratchRegisterBits::encode(scratch_.code());
428  }
429 
430  void Generate(MacroAssembler* masm);
431 };
432 
433 
434 class NumberToStringStub: public CodeStub {
435  public:
437 
438  // Generate code to do a lookup in the number string cache. If the number in
439  // the register object is found in the cache the generated code falls through
440  // with the result in the result register. The object and the result register
441  // can be the same. If the number is not found in the cache the code jumps to
442  // the label not_found with only the content of register object unchanged.
444  Register object,
445  Register result,
446  Register scratch1,
447  Register scratch2,
448  Register scratch3,
449  bool object_is_smi,
450  Label* not_found);
451 
452  private:
453  Major MajorKey() { return NumberToString; }
454  int MinorKey() { return 0; }
455 
456  void Generate(MacroAssembler* masm);
457 };
458 
459 
460 class RecordWriteStub: public CodeStub {
461  public:
463  Register value,
464  Register address,
465  RememberedSetAction remembered_set_action,
466  SaveFPRegsMode fp_mode)
467  : object_(object),
468  value_(value),
469  address_(address),
470  remembered_set_action_(remembered_set_action),
471  save_fp_regs_mode_(fp_mode),
472  regs_(object, // An input reg.
473  address, // An input reg.
474  value) { // One scratch reg.
475  }
476 
477  enum Mode {
481  };
482 
483  virtual bool IsPregenerated();
484  static void GenerateFixedRegStubsAheadOfTime();
485  virtual bool SometimesSetsUpAFrame() { return false; }
486 
487  static void PatchBranchIntoNop(MacroAssembler* masm, int pos) {
488  masm->instr_at_put(pos, (masm->instr_at(pos) & ~B27) | (B24 | B20));
490  }
491 
492  static void PatchNopIntoBranch(MacroAssembler* masm, int pos) {
493  masm->instr_at_put(pos, (masm->instr_at(pos) & ~(B24 | B20)) | B27);
494  ASSERT(Assembler::IsBranch(masm->instr_at(pos)));
495  }
496 
497  static Mode GetMode(Code* stub) {
498  Instr first_instruction = Assembler::instr_at(stub->instruction_start());
499  Instr second_instruction = Assembler::instr_at(stub->instruction_start() +
501 
502  if (Assembler::IsBranch(first_instruction)) {
503  return INCREMENTAL;
504  }
505 
506  ASSERT(Assembler::IsTstImmediate(first_instruction));
507 
508  if (Assembler::IsBranch(second_instruction)) {
509  return INCREMENTAL_COMPACTION;
510  }
511 
512  ASSERT(Assembler::IsTstImmediate(second_instruction));
513 
514  return STORE_BUFFER_ONLY;
515  }
516 
517  static void Patch(Code* stub, Mode mode) {
518  MacroAssembler masm(NULL,
519  stub->instruction_start(),
520  stub->instruction_size());
521  switch (mode) {
522  case STORE_BUFFER_ONLY:
523  ASSERT(GetMode(stub) == INCREMENTAL ||
525  PatchBranchIntoNop(&masm, 0);
527  break;
528  case INCREMENTAL:
529  ASSERT(GetMode(stub) == STORE_BUFFER_ONLY);
530  PatchNopIntoBranch(&masm, 0);
531  break;
533  ASSERT(GetMode(stub) == STORE_BUFFER_ONLY);
535  break;
536  }
537  ASSERT(GetMode(stub) == mode);
539  }
540 
541  private:
542  // This is a helper class for freeing up 3 scratch registers. The input is
543  // two registers that must be preserved and one scratch register provided by
544  // the caller.
545  class RegisterAllocation {
546  public:
547  RegisterAllocation(Register object,
548  Register address,
549  Register scratch0)
550  : object_(object),
551  address_(address),
552  scratch0_(scratch0) {
553  ASSERT(!AreAliased(scratch0, object, address, no_reg));
554  scratch1_ = GetRegThatIsNotOneOf(object_, address_, scratch0_);
555  }
556 
557  void Save(MacroAssembler* masm) {
558  ASSERT(!AreAliased(object_, address_, scratch1_, scratch0_));
559  // We don't have to save scratch0_ because it was given to us as
560  // a scratch register.
561  masm->push(scratch1_);
562  }
563 
564  void Restore(MacroAssembler* masm) {
565  masm->pop(scratch1_);
566  }
567 
568  // If we have to call into C then we need to save and restore all caller-
569  // saved registers that were not already preserved. The scratch registers
570  // will be restored by other means so we don't bother pushing them here.
571  void SaveCallerSaveRegisters(MacroAssembler* masm, SaveFPRegsMode mode) {
572  masm->stm(db_w, sp, (kCallerSaved | lr.bit()) & ~scratch1_.bit());
573  if (mode == kSaveFPRegs) {
574  CpuFeatures::Scope scope(VFP2);
575  masm->sub(sp,
576  sp,
577  Operand(kDoubleSize * (DwVfpRegister::kNumRegisters - 1)));
578  // Save all VFP registers except d0.
579  for (int i = DwVfpRegister::kNumRegisters - 1; i > 0; i--) {
580  DwVfpRegister reg = DwVfpRegister::from_code(i);
581  masm->vstr(reg, MemOperand(sp, (i - 1) * kDoubleSize));
582  }
583  }
584  }
585 
586  inline void RestoreCallerSaveRegisters(MacroAssembler*masm,
587  SaveFPRegsMode mode) {
588  if (mode == kSaveFPRegs) {
589  CpuFeatures::Scope scope(VFP2);
590  // Restore all VFP registers except d0.
591  for (int i = DwVfpRegister::kNumRegisters - 1; i > 0; i--) {
592  DwVfpRegister reg = DwVfpRegister::from_code(i);
593  masm->vldr(reg, MemOperand(sp, (i - 1) * kDoubleSize));
594  }
595  masm->add(sp,
596  sp,
597  Operand(kDoubleSize * (DwVfpRegister::kNumRegisters - 1)));
598  }
599  masm->ldm(ia_w, sp, (kCallerSaved | lr.bit()) & ~scratch1_.bit());
600  }
601 
602  inline Register object() { return object_; }
603  inline Register address() { return address_; }
604  inline Register scratch0() { return scratch0_; }
605  inline Register scratch1() { return scratch1_; }
606 
607  private:
608  Register object_;
609  Register address_;
610  Register scratch0_;
611  Register scratch1_;
612 
613  Register GetRegThatIsNotOneOf(Register r1,
614  Register r2,
615  Register r3) {
616  for (int i = 0; i < Register::kNumAllocatableRegisters; i++) {
617  Register candidate = Register::FromAllocationIndex(i);
618  if (candidate.is(r1)) continue;
619  if (candidate.is(r2)) continue;
620  if (candidate.is(r3)) continue;
621  return candidate;
622  }
623  UNREACHABLE();
624  return no_reg;
625  }
626  friend class RecordWriteStub;
627  };
628 
629  enum OnNoNeedToInformIncrementalMarker {
630  kReturnOnNoNeedToInformIncrementalMarker,
631  kUpdateRememberedSetOnNoNeedToInformIncrementalMarker
632  };
633 
634  void Generate(MacroAssembler* masm);
635  void GenerateIncremental(MacroAssembler* masm, Mode mode);
636  void CheckNeedsToInformIncrementalMarker(
637  MacroAssembler* masm,
638  OnNoNeedToInformIncrementalMarker on_no_need,
639  Mode mode);
640  void InformIncrementalMarker(MacroAssembler* masm, Mode mode);
641 
642  Major MajorKey() { return RecordWrite; }
643 
644  int MinorKey() {
645  return ObjectBits::encode(object_.code()) |
646  ValueBits::encode(value_.code()) |
647  AddressBits::encode(address_.code()) |
648  RememberedSetActionBits::encode(remembered_set_action_) |
649  SaveFPRegsModeBits::encode(save_fp_regs_mode_);
650  }
651 
652  void Activate(Code* code) {
653  code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code);
654  }
655 
656  class ObjectBits: public BitField<int, 0, 4> {};
657  class ValueBits: public BitField<int, 4, 4> {};
658  class AddressBits: public BitField<int, 8, 4> {};
659  class RememberedSetActionBits: public BitField<RememberedSetAction, 12, 1> {};
660  class SaveFPRegsModeBits: public BitField<SaveFPRegsMode, 13, 1> {};
661 
662  Register object_;
663  Register value_;
664  Register address_;
665  RememberedSetAction remembered_set_action_;
666  SaveFPRegsMode save_fp_regs_mode_;
667  Label slow_;
668  RegisterAllocation regs_;
669 };
670 
671 
672 // Enter C code from generated RegExp code in a way that allows
673 // the C code to fix the return address in case of a GC.
674 // Currently only needed on ARM.
675 class RegExpCEntryStub: public CodeStub {
676  public:
678  virtual ~RegExpCEntryStub() {}
679  void Generate(MacroAssembler* masm);
680 
681  private:
682  Major MajorKey() { return RegExpCEntry; }
683  int MinorKey() { return 0; }
684 
685  bool NeedsImmovableCode() { return true; }
686 };
687 
688 
689 // Trampoline stub to call into native code. To call safely into native code
690 // in the presence of compacting GC (which can move code objects) we need to
691 // keep the code which called into native pinned in the memory. Currently the
692 // simplest approach is to generate such stub early enough so it can never be
693 // moved by GC
694 class DirectCEntryStub: public CodeStub {
695  public:
697  void Generate(MacroAssembler* masm);
698  void GenerateCall(MacroAssembler* masm, ExternalReference function);
699  void GenerateCall(MacroAssembler* masm, Register target);
700 
701  private:
702  Major MajorKey() { return DirectCEntry; }
703  int MinorKey() { return 0; }
704 
705  bool NeedsImmovableCode() { return true; }
706 };
707 
708 
710  public:
711  enum Destination {
714  };
715 
716 
717  // Loads smis from r0 and r1 (right and left in binary operations) into
718  // floating point registers. Depending on the destination the values ends up
719  // either d7 and d6 or in r2/r3 and r0/r1 respectively. If the destination is
720  // floating point registers VFP3 must be supported. If core registers are
721  // requested when VFP3 is supported d6 and d7 will be scratched.
722  static void LoadSmis(MacroAssembler* masm,
723  Destination destination,
724  Register scratch1,
725  Register scratch2);
726 
727  // Loads objects from r0 and r1 (right and left in binary operations) into
728  // floating point registers. Depending on the destination the values ends up
729  // either d7 and d6 or in r2/r3 and r0/r1 respectively. If the destination is
730  // floating point registers VFP3 must be supported. If core registers are
731  // requested when VFP3 is supported d6 and d7 will still be scratched. If
732  // either r0 or r1 is not a number (not smi and not heap number object) the
733  // not_number label is jumped to with r0 and r1 intact.
734  static void LoadOperands(MacroAssembler* masm,
736  Register heap_number_map,
737  Register scratch1,
738  Register scratch2,
739  Label* not_number);
740 
741  // Convert the smi or heap number in object to an int32 using the rules
742  // for ToInt32 as described in ECMAScript 9.5.: the value is truncated
743  // and brought into the range -2^31 .. +2^31 - 1.
744  static void ConvertNumberToInt32(MacroAssembler* masm,
745  Register object,
746  Register dst,
747  Register heap_number_map,
748  Register scratch1,
749  Register scratch2,
750  Register scratch3,
751  DwVfpRegister double_scratch,
752  Label* not_int32);
753 
754  // Converts the integer (untagged smi) in |int_scratch| to a double, storing
755  // the result either in |double_dst| or |dst2:dst1|, depending on
756  // |destination|.
757  // Warning: The value in |int_scratch| will be changed in the process!
758  static void ConvertIntToDouble(MacroAssembler* masm,
759  Register int_scratch,
760  Destination destination,
761  DwVfpRegister double_dst,
762  Register dst1,
763  Register dst2,
764  Register scratch2,
765  SwVfpRegister single_scratch);
766 
767  // Load the number from object into double_dst in the double format.
768  // Control will jump to not_int32 if the value cannot be exactly represented
769  // by a 32-bit integer.
770  // Floating point value in the 32-bit integer range that are not exact integer
771  // won't be loaded.
772  static void LoadNumberAsInt32Double(MacroAssembler* masm,
773  Register object,
774  Destination destination,
775  DwVfpRegister double_dst,
776  DwVfpRegister double_scratch,
777  Register dst1,
778  Register dst2,
779  Register heap_number_map,
780  Register scratch1,
781  Register scratch2,
782  SwVfpRegister single_scratch,
783  Label* not_int32);
784 
785  // Loads the number from object into dst as a 32-bit integer.
786  // Control will jump to not_int32 if the object cannot be exactly represented
787  // by a 32-bit integer.
788  // Floating point value in the 32-bit integer range that are not exact integer
789  // won't be converted.
790  // scratch3 is not used when VFP3 is supported.
791  static void LoadNumberAsInt32(MacroAssembler* masm,
792  Register object,
793  Register dst,
794  Register heap_number_map,
795  Register scratch1,
796  Register scratch2,
797  Register scratch3,
798  DwVfpRegister double_scratch0,
799  DwVfpRegister double_scratch1,
800  Label* not_int32);
801 
802  // Generate non VFP3 code to check if a double can be exactly represented by a
803  // 32-bit integer. This does not check for 0 or -0, which need
804  // to be checked for separately.
805  // Control jumps to not_int32 if the value is not a 32-bit integer, and falls
806  // through otherwise.
807  // src1 and src2 will be cloberred.
808  //
809  // Expected input:
810  // - src1: higher (exponent) part of the double value.
811  // - src2: lower (mantissa) part of the double value.
812  // Output status:
813  // - dst: 32 higher bits of the mantissa. (mantissa[51:20])
814  // - src2: contains 1.
815  // - other registers are clobbered.
816  static void DoubleIs32BitInteger(MacroAssembler* masm,
817  Register src1,
818  Register src2,
819  Register dst,
820  Register scratch,
821  Label* not_int32);
822 
823  // Generates code to call a C function to do a double operation using core
824  // registers. (Used when VFP3 is not supported.)
825  // This code never falls through, but returns with a heap number containing
826  // the result in r0.
827  // Register heapnumber_result must be a heap number in which the
828  // result of the operation will be stored.
829  // Requires the following layout on entry:
830  // r0: Left value (least significant part of mantissa).
831  // r1: Left value (sign, exponent, top of mantissa).
832  // r2: Right value (least significant part of mantissa).
833  // r3: Right value (sign, exponent, top of mantissa).
835  Token::Value op,
836  Register heap_number_result,
837  Register scratch);
838 
839  private:
840  static void LoadNumber(MacroAssembler* masm,
842  Register object,
843  DwVfpRegister dst,
844  Register dst1,
845  Register dst2,
846  Register heap_number_map,
847  Register scratch1,
848  Register scratch2,
849  Label* not_number);
850 };
851 
852 
853 class StringDictionaryLookupStub: public CodeStub {
854  public:
856 
857  explicit StringDictionaryLookupStub(LookupMode mode) : mode_(mode) { }
858 
859  void Generate(MacroAssembler* masm);
860 
861  static void GenerateNegativeLookup(MacroAssembler* masm,
862  Label* miss,
863  Label* done,
864  Register receiver,
865  Register properties,
866  Handle<String> name,
867  Register scratch0);
868 
869  static void GeneratePositiveLookup(MacroAssembler* masm,
870  Label* miss,
871  Label* done,
872  Register elements,
873  Register name,
874  Register r0,
875  Register r1);
876 
877  virtual bool SometimesSetsUpAFrame() { return false; }
878 
879  private:
880  static const int kInlinedProbes = 4;
881  static const int kTotalProbes = 20;
882 
883  static const int kCapacityOffset =
886 
887  static const int kElementsStartOffset =
890 
891  Major MajorKey() { return StringDictionaryLookup; }
892 
893  int MinorKey() {
894  return LookupModeBits::encode(mode_);
895  }
896 
897  class LookupModeBits: public BitField<LookupMode, 0, 1> {};
898 
899  LookupMode mode_;
900 };
901 
902 
903 } } // namespace v8::internal
904 
905 #endif // V8_ARM_CODE_STUBS_ARM_H_
static bool IsBranch(Instr instr)
static const int kNumRegisters
const RegList kCallerSaved
Definition: frames-arm.h:75
static Mode GetMode(Code *stub)
static void Patch(Code *stub, Mode mode)
RecordWriteStub(Register object, Register value, Register address, RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode)
const Register r3
virtual bool SometimesSetsUpAFrame()
static void GenerateFixedRegStubsAheadOfTime()
void instr_at_put(int pos, Instr instr)
static void GenerateCopyCharacters(MacroAssembler *masm, Register dest, Register src, Register count, Register scratch, bool ascii)
UnaryOpStub(Token::Value op, UnaryOverwriteMode mode, UnaryOpIC::TypeInfo operand_type=UnaryOpIC::UNINITIALIZED)
static void LoadNumberAsInt32Double(MacroAssembler *masm, Register object, Destination destination, DwVfpRegister double_dst, DwVfpRegister double_scratch, Register dst1, Register dst2, Register heap_number_map, Register scratch1, Register scratch2, SwVfpRegister single_scratch, Label *not_int32)
virtual ~RegExpCEntryStub()
static void DoubleIs32BitInteger(MacroAssembler *masm, Register src1, Register src2, Register dst, Register scratch, Label *not_int32)
static void GenerateCopyCharactersLong(MacroAssembler *masm, Register dest, Register src, Register count, Register scratch1, Register scratch2, Register scratch3, Register scratch4, Register scratch5, int flags)
void Generate(MacroAssembler *masm)
static void GenerateHashGetHash(MacroAssembler *masm, Register hash)
static bool IsSupported(CpuFeature f)
bool AreAliased(Register r1, Register r2, Register r3, Register r4)
#define ASSERT(condition)
Definition: checks.h:270
static void LoadOperands(MacroAssembler *masm, FloatingPointHelper::Destination destination, Register heap_number_map, Register scratch1, Register scratch2, Label *not_number)
WriteInt32ToHeapNumberStub(Register the_int, Register the_heap_number, Register scratch)
RegExpCEntryStub()
static void GenerateCompareFlatAsciiStrings(MacroAssembler *masm, Register left, Register right, Register scratch1, Register scratch2, Register scratch3, Register scratch4)
const Register r2
static DwVfpRegister from_code(int code)
BinaryOpStub(Token::Value op, OverwriteMode mode)
static State ToState(TypeInfo type_info)
Definition: ic.cc:2321
static void GenerateNegativeLookup(MacroAssembler *masm, Label *miss, Label *done, Register receiver, Register properties, Handle< String > name, Register scratch0)
Handle< String > SubString(Handle< String > str, int start, int end, PretenureFlag pretenure)
Definition: handles.cc:326
const Register sp
#define UNREACHABLE()
Definition: checks.h:50
static void GenerateFlatAsciiStringEquals(MacroAssembler *masm, Register left, Register right, Register scratch1, Register scratch2, Register scratch3)
const int kDoubleSize
Definition: globals.h:218
byte * instruction_start()
Definition: objects-inl.h:4649
const int kPointerSize
Definition: globals.h:220
static void LoadSmis(MacroAssembler *masm, Destination destination, Register scratch1, Register scratch2)
static void CallCCodeForDoubleOperation(MacroAssembler *masm, Token::Value op, Register heap_number_result, Register scratch)
static Register FromAllocationIndex(int index)
Definition: assembler-arm.h:82
static void ConvertNumberToInt32(MacroAssembler *masm, Register object, Register dst, Register heap_number_map, Register scratch1, Register scratch2, Register scratch3, DwVfpRegister double_scratch, Label *not_int32)
static State ToState(TypeInfo type_info)
Definition: ic.cc:2252
static void LoadNumberAsInt32(MacroAssembler *masm, Register object, Register dst, Register heap_number_map, Register scratch1, Register scratch2, Register scratch3, DwVfpRegister double_scratch0, DwVfpRegister double_scratch1, Label *not_int32)
static void PatchBranchIntoNop(MacroAssembler *masm, int pos)
static void GenerateHashAddCharacter(MacroAssembler *masm, Register hash, Register character)
void Generate(MacroAssembler *masm)
const Register r0
static bool IsTstImmediate(Instr instr)
static const int kHeaderSize
Definition: objects.h:2296
const Register lr
void Generate(MacroAssembler *masm)
void GenerateCall(MacroAssembler *masm, ExternalReference function)
const Register r1
static void ConvertIntToDouble(MacroAssembler *masm, Register int_scratch, Destination destination, DwVfpRegister double_dst, Register dst1, Register dst2, Register scratch2, SwVfpRegister single_scratch)
void Generate(MacroAssembler *masm)
static void GeneratePositiveLookup(MacroAssembler *masm, Label *miss, Label *done, Register elements, Register name, Register r0, Register r1)
BinaryOpStub(int key, BinaryOpIC::TypeInfo operands_type, BinaryOpIC::TypeInfo result_type=BinaryOpIC::UNINITIALIZED)
static const int kNumAllocatableRegisters
Definition: assembler-arm.h:74
TranscendentalCacheStub(TranscendentalCache::Type type, ArgumentType argument_type)
static void PatchNopIntoBranch(MacroAssembler *masm, int pos)
static void GenerateLookupNumberStringCache(MacroAssembler *masm, Register object, Register result, Register scratch1, Register scratch2, Register scratch3, bool object_is_smi, Label *not_found)
static const int kInstrSize
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
Definition: flags.cc:301
const Register no_reg
static void GenerateTwoCharacterSymbolTableProbe(MacroAssembler *masm, Register c1, Register c2, Register scratch1, Register scratch2, Register scratch3, Register scratch4, Register scratch5, Label *not_found)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
static void FlushICache(void *start, size_t size)
static const int kTranscendentalTypeBits
Definition: heap.h:2640
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if expose natives in global object expose gc extension number of stack frames to capture disable builtin natives files print a stack trace if an assertion failure occurs use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations prepare for turning on always opt minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions automatically set the debug break flag when debugger commands are in the queue always cause a debug break before aborting maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print more details following each garbage collection print amount of external allocated memory after each time it is adjusted flush code that we expect not to use again before full gc do incremental marking steps track object counts and memory usage use caching Perform compaction on every full GC Never perform compaction on full GC testing only Compact code space on full incremental collections Default seed for initializing random allows verbose printing trace parsing and preparsing Check icache flushes in ARM and MIPS simulator Stack alingment in bytes in print stack trace when throwing exceptions randomize hashes to avoid predictable hash Fixed seed to use to hash property activate a timer that switches between V8 threads testing_bool_flag float flag Seed used for threading test randomness A filename with extra code to be included in the Print usage including flags
Definition: flags.cc:495
StringAddStub(StringAddFlags flags)
StoreBufferOverflowStub(SaveFPRegsMode save_fp)
DirectCEntryStub()
static void GenerateHashInit(MacroAssembler *masm, Register hash, Register character)
void Generate(MacroAssembler *masm)