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-mips.h
Go to the documentation of this file.
1 // Copyright 2011 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_MIPS_CODE_STUBS_ARM_H_
29 #define V8_MIPS_CODE_STUBS_ARM_H_
30 
31 #include "ic-inl.h"
32 
33 
34 namespace v8 {
35 namespace internal {
36 
37 
38 // Compute a transcendental math function natively, or call the
39 // TranscendentalCache runtime function.
40 class TranscendentalCacheStub: public CodeStub {
41  public:
42  enum ArgumentType {
45  };
46 
48  ArgumentType argument_type)
49  : type_(type), argument_type_(argument_type) { }
50  void Generate(MacroAssembler* masm);
51  private:
53  ArgumentType argument_type_;
54  void GenerateCallCFunction(MacroAssembler* masm, Register scratch);
55 
56  Major MajorKey() { return TranscendentalCache; }
57  int MinorKey() { return type_ | argument_type_; }
58  Runtime::FunctionId RuntimeFunction();
59 };
60 
61 
62 class StoreBufferOverflowStub: public CodeStub {
63  public:
65  : save_doubles_(save_fp) { }
66 
67  void Generate(MacroAssembler* masm);
68 
69  virtual bool IsPregenerated();
71  virtual bool SometimesSetsUpAFrame() { return false; }
72 
73  private:
74  SaveFPRegsMode save_doubles_;
75 
76  Major MajorKey() { return StoreBufferOverflow; }
77  int MinorKey() { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; }
78 };
79 
80 
81 class UnaryOpStub: public CodeStub {
82  public:
84  UnaryOverwriteMode mode,
86  : op_(op),
87  mode_(mode),
88  operand_type_(operand_type) {
89  }
90 
91  private:
92  Token::Value op_;
93  UnaryOverwriteMode mode_;
94 
95  // Operand type information determined at runtime.
96  UnaryOpIC::TypeInfo operand_type_;
97 
98  virtual void PrintName(StringStream* stream);
99 
100  class ModeBits: public BitField<UnaryOverwriteMode, 0, 1> {};
101  class OpBits: public BitField<Token::Value, 1, 7> {};
102  class OperandTypeInfoBits: public BitField<UnaryOpIC::TypeInfo, 8, 3> {};
103 
104  Major MajorKey() { return UnaryOp; }
105  int MinorKey() {
106  return ModeBits::encode(mode_)
107  | OpBits::encode(op_)
108  | OperandTypeInfoBits::encode(operand_type_);
109  }
110 
111  // Note: A lot of the helper functions below will vanish when we use virtual
112  // function instead of switch more often.
113  void Generate(MacroAssembler* masm);
114 
115  void GenerateTypeTransition(MacroAssembler* masm);
116 
117  void GenerateSmiStub(MacroAssembler* masm);
118  void GenerateSmiStubSub(MacroAssembler* masm);
119  void GenerateSmiStubBitNot(MacroAssembler* masm);
120  void GenerateSmiCodeSub(MacroAssembler* masm, Label* non_smi, Label* slow);
121  void GenerateSmiCodeBitNot(MacroAssembler* masm, Label* slow);
122 
123  void GenerateHeapNumberStub(MacroAssembler* masm);
124  void GenerateHeapNumberStubSub(MacroAssembler* masm);
125  void GenerateHeapNumberStubBitNot(MacroAssembler* masm);
126  void GenerateHeapNumberCodeSub(MacroAssembler* masm, Label* slow);
127  void GenerateHeapNumberCodeBitNot(MacroAssembler* masm, Label* slow);
128 
129  void GenerateGenericStub(MacroAssembler* masm);
130  void GenerateGenericStubSub(MacroAssembler* masm);
131  void GenerateGenericStubBitNot(MacroAssembler* masm);
132  void GenerateGenericCodeFallback(MacroAssembler* masm);
133 
134  virtual int GetCodeKind() { return Code::UNARY_OP_IC; }
135 
136  virtual InlineCacheState GetICState() {
137  return UnaryOpIC::ToState(operand_type_);
138  }
139 
140  virtual void FinishCode(Handle<Code> code) {
141  code->set_unary_op_type(operand_type_);
142  }
143 };
144 
145 
146 class BinaryOpStub: public CodeStub {
147  public:
149  : op_(op),
150  mode_(mode),
151  operands_type_(BinaryOpIC::UNINITIALIZED),
152  result_type_(BinaryOpIC::UNINITIALIZED) {
153  use_fpu_ = CpuFeatures::IsSupported(FPU);
154  ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
155  }
156 
158  int key,
159  BinaryOpIC::TypeInfo operands_type,
161  : op_(OpBits::decode(key)),
162  mode_(ModeBits::decode(key)),
163  use_fpu_(FPUBits::decode(key)),
164  operands_type_(operands_type),
165  result_type_(result_type) { }
166 
167  private:
168  enum SmiCodeGenerateHeapNumberResults {
169  ALLOW_HEAPNUMBER_RESULTS,
170  NO_HEAPNUMBER_RESULTS
171  };
172 
173  Token::Value op_;
174  OverwriteMode mode_;
175  bool use_fpu_;
176 
177  // Operand type information determined at runtime.
178  BinaryOpIC::TypeInfo operands_type_;
179  BinaryOpIC::TypeInfo result_type_;
180 
181  virtual void PrintName(StringStream* stream);
182 
183  // Minor key encoding in 16 bits RRRTTTVOOOOOOOMM.
184  class ModeBits: public BitField<OverwriteMode, 0, 2> {};
185  class OpBits: public BitField<Token::Value, 2, 7> {};
186  class FPUBits: public BitField<bool, 9, 1> {};
187  class OperandTypeInfoBits: public BitField<BinaryOpIC::TypeInfo, 10, 3> {};
188  class ResultTypeInfoBits: public BitField<BinaryOpIC::TypeInfo, 13, 3> {};
189 
190  Major MajorKey() { return BinaryOp; }
191  int MinorKey() {
192  return OpBits::encode(op_)
193  | ModeBits::encode(mode_)
194  | FPUBits::encode(use_fpu_)
195  | OperandTypeInfoBits::encode(operands_type_)
196  | ResultTypeInfoBits::encode(result_type_);
197  }
198 
199  void Generate(MacroAssembler* masm);
200  void GenerateGeneric(MacroAssembler* masm);
201  void GenerateSmiSmiOperation(MacroAssembler* masm);
202  void GenerateFPOperation(MacroAssembler* masm,
203  bool smi_operands,
204  Label* not_numbers,
205  Label* gc_required);
206  void GenerateSmiCode(MacroAssembler* masm,
207  Label* use_runtime,
208  Label* gc_required,
209  SmiCodeGenerateHeapNumberResults heapnumber_results);
210  void GenerateLoadArguments(MacroAssembler* masm);
211  void GenerateReturn(MacroAssembler* masm);
212  void GenerateUninitializedStub(MacroAssembler* masm);
213  void GenerateSmiStub(MacroAssembler* masm);
214  void GenerateInt32Stub(MacroAssembler* masm);
215  void GenerateHeapNumberStub(MacroAssembler* masm);
216  void GenerateOddballStub(MacroAssembler* masm);
217  void GenerateStringStub(MacroAssembler* masm);
218  void GenerateBothStringStub(MacroAssembler* masm);
219  void GenerateGenericStub(MacroAssembler* masm);
220  void GenerateAddStrings(MacroAssembler* masm);
221  void GenerateCallRuntime(MacroAssembler* masm);
222 
223  void GenerateHeapResultAllocation(MacroAssembler* masm,
224  Register result,
225  Register heap_number_map,
226  Register scratch1,
227  Register scratch2,
228  Label* gc_required);
229  void GenerateRegisterArgsPush(MacroAssembler* masm);
230  void GenerateTypeTransition(MacroAssembler* masm);
231  void GenerateTypeTransitionWithSavedArgs(MacroAssembler* masm);
232 
233  virtual int GetCodeKind() { return Code::BINARY_OP_IC; }
234 
235  virtual InlineCacheState GetICState() {
236  return BinaryOpIC::ToState(operands_type_);
237  }
238 
239  virtual void FinishCode(Handle<Code> code) {
240  code->set_binary_op_type(operands_type_);
241  code->set_binary_op_result_type(result_type_);
242  }
243 
244  friend class CodeGenerator;
245 };
246 
247 
248 class StringHelper : public AllStatic {
249  public:
250  // Generate code for copying characters using a simple loop. This should only
251  // be used in places where the number of characters is small and the
252  // additional setup and checking in GenerateCopyCharactersLong adds too much
253  // overhead. Copying of overlapping regions is not supported.
254  // Dest register ends at the position after the last character written.
255  static void GenerateCopyCharacters(MacroAssembler* masm,
256  Register dest,
257  Register src,
258  Register count,
259  Register scratch,
260  bool ascii);
261 
262  // Generate code for copying a large number of characters. This function
263  // is allowed to spend extra time setting up conditions to make copying
264  // faster. Copying of overlapping regions is not supported.
265  // Dest register ends at the position after the last character written.
266  static void GenerateCopyCharactersLong(MacroAssembler* masm,
267  Register dest,
268  Register src,
269  Register count,
270  Register scratch1,
271  Register scratch2,
272  Register scratch3,
273  Register scratch4,
274  Register scratch5,
275  int flags);
276 
277 
278  // Probe the symbol table for a two character string. If the string is
279  // not found by probing a jump to the label not_found is performed. This jump
280  // does not guarantee that the string is not in the symbol table. If the
281  // string is found the code falls through with the string in register r0.
282  // Contents of both c1 and c2 registers are modified. At the exit c1 is
283  // guaranteed to contain halfword with low and high bytes equal to
284  // initial contents of c1 and c2 respectively.
285  static void GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
286  Register c1,
287  Register c2,
288  Register scratch1,
289  Register scratch2,
290  Register scratch3,
291  Register scratch4,
292  Register scratch5,
293  Label* not_found);
294 
295  // Generate string hash.
296  static void GenerateHashInit(MacroAssembler* masm,
297  Register hash,
298  Register character);
299 
300  static void GenerateHashAddCharacter(MacroAssembler* masm,
301  Register hash,
302  Register character);
303 
304  static void GenerateHashGetHash(MacroAssembler* masm,
305  Register hash);
306 
307  private:
308  DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper);
309 };
310 
311 
312 // Flag that indicates how to generate code for the stub StringAddStub.
315  // Omit left string check in stub (left is definitely a string).
317  // Omit right string check in stub (right is definitely a string).
319  // Omit both string checks in stub.
322 };
323 
324 
325 class StringAddStub: public CodeStub {
326  public:
327  explicit StringAddStub(StringAddFlags flags) : flags_(flags) {}
328 
329  private:
330  Major MajorKey() { return StringAdd; }
331  int MinorKey() { return flags_; }
332 
333  void Generate(MacroAssembler* masm);
334 
335  void GenerateConvertArgument(MacroAssembler* masm,
336  int stack_offset,
337  Register arg,
338  Register scratch1,
339  Register scratch2,
340  Register scratch3,
341  Register scratch4,
342  Label* slow);
343 
344  const StringAddFlags flags_;
345 };
346 
347 
348 class SubStringStub: public CodeStub {
349  public:
351 
352  private:
353  Major MajorKey() { return SubString; }
354  int MinorKey() { return 0; }
355 
356  void Generate(MacroAssembler* masm);
357 };
358 
359 
360 class StringCompareStub: public CodeStub {
361  public:
363 
364  // Compare two flat ASCII strings and returns result in v0.
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 v0.
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  Register scratch3,
394  Label* chars_not_equal);
395 };
396 
397 
398 // This stub can convert a signed int32 to a heap number (double). It does
399 // not work for int32s that are in Smi range! No GC occurs during this stub
400 // so you don't have to set up the frame.
401 class WriteInt32ToHeapNumberStub : public CodeStub {
402  public:
404  Register the_heap_number,
405  Register scratch,
406  Register scratch2)
407  : the_int_(the_int),
408  the_heap_number_(the_heap_number),
409  scratch_(scratch),
410  sign_(scratch2) {
411  ASSERT(IntRegisterBits::is_valid(the_int_.code()));
412  ASSERT(HeapNumberRegisterBits::is_valid(the_heap_number_.code()));
413  ASSERT(ScratchRegisterBits::is_valid(scratch_.code()));
414  ASSERT(SignRegisterBits::is_valid(sign_.code()));
415  }
416 
417  bool IsPregenerated();
418  static void GenerateFixedRegStubsAheadOfTime();
419 
420  private:
421  Register the_int_;
422  Register the_heap_number_;
423  Register scratch_;
424  Register sign_;
425 
426  // Minor key encoding in 16 bits.
427  class IntRegisterBits: public BitField<int, 0, 4> {};
428  class HeapNumberRegisterBits: public BitField<int, 4, 4> {};
429  class ScratchRegisterBits: public BitField<int, 8, 4> {};
430  class SignRegisterBits: public BitField<int, 12, 4> {};
431 
432  Major MajorKey() { return WriteInt32ToHeapNumber; }
433  int MinorKey() {
434  // Encode the parameters in a unique 16 bit value.
435  return IntRegisterBits::encode(the_int_.code())
436  | HeapNumberRegisterBits::encode(the_heap_number_.code())
437  | ScratchRegisterBits::encode(scratch_.code())
438  | SignRegisterBits::encode(sign_.code());
439  }
440 
441  void Generate(MacroAssembler* masm);
442 };
443 
444 
445 class NumberToStringStub: public CodeStub {
446  public:
448 
449  // Generate code to do a lookup in the number string cache. If the number in
450  // the register object is found in the cache the generated code falls through
451  // with the result in the result register. The object and the result register
452  // can be the same. If the number is not found in the cache the code jumps to
453  // the label not_found with only the content of register object unchanged.
455  Register object,
456  Register result,
457  Register scratch1,
458  Register scratch2,
459  Register scratch3,
460  bool object_is_smi,
461  Label* not_found);
462 
463  private:
464  Major MajorKey() { return NumberToString; }
465  int MinorKey() { return 0; }
466 
467  void Generate(MacroAssembler* masm);
468 };
469 
470 
471 class RecordWriteStub: public CodeStub {
472  public:
474  Register value,
475  Register address,
476  RememberedSetAction remembered_set_action,
477  SaveFPRegsMode fp_mode)
478  : object_(object),
479  value_(value),
480  address_(address),
481  remembered_set_action_(remembered_set_action),
482  save_fp_regs_mode_(fp_mode),
483  regs_(object, // An input reg.
484  address, // An input reg.
485  value) { // One scratch reg.
486  }
487 
488  enum Mode {
490  INCREMENTAL,
492  };
493 
494  virtual bool IsPregenerated();
495  static void GenerateFixedRegStubsAheadOfTime();
496  virtual bool SometimesSetsUpAFrame() { return false; }
497 
498  static void PatchBranchIntoNop(MacroAssembler* masm, int pos) {
499  const unsigned offset = masm->instr_at(pos) & kImm16Mask;
500  masm->instr_at_put(pos, BNE | (zero_reg.code() << kRsShift) |
501  (zero_reg.code() << kRtShift) | (offset & kImm16Mask));
502  ASSERT(Assembler::IsBne(masm->instr_at(pos)));
503  }
504 
505  static void PatchNopIntoBranch(MacroAssembler* masm, int pos) {
506  const unsigned offset = masm->instr_at(pos) & kImm16Mask;
507  masm->instr_at_put(pos, BEQ | (zero_reg.code() << kRsShift) |
508  (zero_reg.code() << kRtShift) | (offset & kImm16Mask));
509  ASSERT(Assembler::IsBeq(masm->instr_at(pos)));
510  }
511 
512  static Mode GetMode(Code* stub) {
513  Instr first_instruction = Assembler::instr_at(stub->instruction_start());
514  Instr second_instruction = Assembler::instr_at(stub->instruction_start() +
516 
517  if (Assembler::IsBeq(first_instruction)) {
518  return INCREMENTAL;
519  }
520 
521  ASSERT(Assembler::IsBne(first_instruction));
522 
523  if (Assembler::IsBeq(second_instruction)) {
524  return INCREMENTAL_COMPACTION;
525  }
526 
527  ASSERT(Assembler::IsBne(second_instruction));
528 
529  return STORE_BUFFER_ONLY;
530  }
531 
532  static void Patch(Code* stub, Mode mode) {
533  MacroAssembler masm(NULL,
534  stub->instruction_start(),
535  stub->instruction_size());
536  switch (mode) {
537  case STORE_BUFFER_ONLY:
538  ASSERT(GetMode(stub) == INCREMENTAL ||
540  PatchBranchIntoNop(&masm, 0);
542  break;
543  case INCREMENTAL:
544  ASSERT(GetMode(stub) == STORE_BUFFER_ONLY);
545  PatchNopIntoBranch(&masm, 0);
546  break;
548  ASSERT(GetMode(stub) == STORE_BUFFER_ONLY);
550  break;
551  }
552  ASSERT(GetMode(stub) == mode);
554  }
555 
556  private:
557  // This is a helper class for freeing up 3 scratch registers. The input is
558  // two registers that must be preserved and one scratch register provided by
559  // the caller.
560  class RegisterAllocation {
561  public:
562  RegisterAllocation(Register object,
563  Register address,
564  Register scratch0)
565  : object_(object),
566  address_(address),
567  scratch0_(scratch0) {
568  ASSERT(!AreAliased(scratch0, object, address, no_reg));
569  scratch1_ = GetRegThatIsNotOneOf(object_, address_, scratch0_);
570  }
571 
572  void Save(MacroAssembler* masm) {
573  ASSERT(!AreAliased(object_, address_, scratch1_, scratch0_));
574  // We don't have to save scratch0_ because it was given to us as
575  // a scratch register.
576  masm->push(scratch1_);
577  }
578 
579  void Restore(MacroAssembler* masm) {
580  masm->pop(scratch1_);
581  }
582 
583  // If we have to call into C then we need to save and restore all caller-
584  // saved registers that were not already preserved. The scratch registers
585  // will be restored by other means so we don't bother pushing them here.
586  void SaveCallerSaveRegisters(MacroAssembler* masm, SaveFPRegsMode mode) {
587  masm->MultiPush((kJSCallerSaved | ra.bit()) & ~scratch1_.bit());
588  if (mode == kSaveFPRegs) {
589  CpuFeatures::Scope scope(FPU);
590  masm->MultiPushFPU(kCallerSavedFPU);
591  }
592  }
593 
594  inline void RestoreCallerSaveRegisters(MacroAssembler*masm,
595  SaveFPRegsMode mode) {
596  if (mode == kSaveFPRegs) {
597  CpuFeatures::Scope scope(FPU);
598  masm->MultiPopFPU(kCallerSavedFPU);
599  }
600  masm->MultiPop((kJSCallerSaved | ra.bit()) & ~scratch1_.bit());
601  }
602 
603  inline Register object() { return object_; }
604  inline Register address() { return address_; }
605  inline Register scratch0() { return scratch0_; }
606  inline Register scratch1() { return scratch1_; }
607 
608  private:
609  Register object_;
610  Register address_;
611  Register scratch0_;
612  Register scratch1_;
613 
614  Register GetRegThatIsNotOneOf(Register r1,
615  Register r2,
616  Register r3) {
617  for (int i = 0; i < Register::kNumAllocatableRegisters; i++) {
618  Register candidate = Register::FromAllocationIndex(i);
619  if (candidate.is(r1)) continue;
620  if (candidate.is(r2)) continue;
621  if (candidate.is(r3)) continue;
622  return candidate;
623  }
624  UNREACHABLE();
625  return no_reg;
626  }
627  friend class RecordWriteStub;
628  };
629 
630  enum OnNoNeedToInformIncrementalMarker {
631  kReturnOnNoNeedToInformIncrementalMarker,
632  kUpdateRememberedSetOnNoNeedToInformIncrementalMarker
633  };
634 
635  void Generate(MacroAssembler* masm);
636  void GenerateIncremental(MacroAssembler* masm, Mode mode);
637  void CheckNeedsToInformIncrementalMarker(
638  MacroAssembler* masm,
639  OnNoNeedToInformIncrementalMarker on_no_need,
640  Mode mode);
641  void InformIncrementalMarker(MacroAssembler* masm, Mode mode);
642 
643  Major MajorKey() { return RecordWrite; }
644 
645  int MinorKey() {
646  return ObjectBits::encode(object_.code()) |
647  ValueBits::encode(value_.code()) |
648  AddressBits::encode(address_.code()) |
649  RememberedSetActionBits::encode(remembered_set_action_) |
650  SaveFPRegsModeBits::encode(save_fp_regs_mode_);
651  }
652 
653  void Activate(Code* code) {
654  code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code);
655  }
656 
657  class ObjectBits: public BitField<int, 0, 5> {};
658  class ValueBits: public BitField<int, 5, 5> {};
659  class AddressBits: public BitField<int, 10, 5> {};
660  class RememberedSetActionBits: public BitField<RememberedSetAction, 15, 1> {};
661  class SaveFPRegsModeBits: public BitField<SaveFPRegsMode, 16, 1> {};
662 
663  Register object_;
664  Register value_;
665  Register address_;
666  RememberedSetAction remembered_set_action_;
667  SaveFPRegsMode save_fp_regs_mode_;
668  Label slow_;
669  RegisterAllocation regs_;
670 };
671 
672 
673 // Enter C code from generated RegExp code in a way that allows
674 // the C code to fix the return address in case of a GC.
675 // Currently only needed on ARM and MIPS.
676 class RegExpCEntryStub: public CodeStub {
677  public:
679  virtual ~RegExpCEntryStub() {}
680  void Generate(MacroAssembler* masm);
681 
682  private:
683  Major MajorKey() { return RegExpCEntry; }
684  int MinorKey() { return 0; }
685 
686  bool NeedsImmovableCode() { return true; }
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,
699  ExternalReference function);
700  void GenerateCall(MacroAssembler* masm, Register target);
701 
702  private:
703  Major MajorKey() { return DirectCEntry; }
704  int MinorKey() { return 0; }
705 
706  bool NeedsImmovableCode() { return true; }
707 };
708 
709 class FloatingPointHelper : public AllStatic {
710  public:
711  enum Destination {
714  };
715 
716 
717  // Loads smis from a0 and a1 (right and left in binary operations) into
718  // floating point registers. Depending on the destination the values ends up
719  // either f14 and f12 or in a2/a3 and a0/a1 respectively. If the destination
720  // is floating point registers FPU must be supported. If core registers are
721  // requested when FPU is supported f12 and f14 will be scratched.
722  static void LoadSmis(MacroAssembler* masm,
723  Destination destination,
724  Register scratch1,
725  Register scratch2);
726 
727  // Loads objects from a0 and a1 (right and left in binary operations) into
728  // floating point registers. Depending on the destination the values ends up
729  // either f14 and f12 or in a2/a3 and a0/a1 respectively. If the destination
730  // is floating point registers FPU must be supported. If core registers are
731  // requested when FPU is supported f12 and f14 will still be scratched. If
732  // either a0 or a1 is not a number (not smi and not heap number object) the
733  // not_number label is jumped to with a0 and a1 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  FPURegister 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  FPURegister double_dst,
762  Register dst1,
763  Register dst2,
764  Register scratch2,
765  FPURegister 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  FPURegister double_dst,
776  Register dst1,
777  Register dst2,
778  Register heap_number_map,
779  Register scratch1,
780  Register scratch2,
781  FPURegister single_scratch,
782  Label* not_int32);
783 
784  // Loads the number from object into dst as a 32-bit integer.
785  // Control will jump to not_int32 if the object cannot be exactly represented
786  // by a 32-bit integer.
787  // Floating point value in the 32-bit integer range that are not exact integer
788  // won't be converted.
789  // scratch3 is not used when FPU is supported.
790  static void LoadNumberAsInt32(MacroAssembler* masm,
791  Register object,
792  Register dst,
793  Register heap_number_map,
794  Register scratch1,
795  Register scratch2,
796  Register scratch3,
797  FPURegister double_scratch,
798  Label* not_int32);
799 
800  // Generate non FPU code to check if a double can be exactly represented by a
801  // 32-bit integer. This does not check for 0 or -0, which need
802  // to be checked for separately.
803  // Control jumps to not_int32 if the value is not a 32-bit integer, and falls
804  // through otherwise.
805  // src1 and src2 will be cloberred.
806  //
807  // Expected input:
808  // - src1: higher (exponent) part of the double value.
809  // - src2: lower (mantissa) part of the double value.
810  // Output status:
811  // - dst: 32 higher bits of the mantissa. (mantissa[51:20])
812  // - src2: contains 1.
813  // - other registers are clobbered.
814  static void DoubleIs32BitInteger(MacroAssembler* masm,
815  Register src1,
816  Register src2,
817  Register dst,
818  Register scratch,
819  Label* not_int32);
820 
821  // Generates code to call a C function to do a double operation using core
822  // registers. (Used when FPU is not supported.)
823  // This code never falls through, but returns with a heap number containing
824  // the result in v0.
825  // Register heapnumber_result must be a heap number in which the
826  // result of the operation will be stored.
827  // Requires the following layout on entry:
828  // a0: Left value (least significant part of mantissa).
829  // a1: Left value (sign, exponent, top of mantissa).
830  // a2: Right value (least significant part of mantissa).
831  // a3: Right value (sign, exponent, top of mantissa).
833  Token::Value op,
834  Register heap_number_result,
835  Register scratch);
836 
837  private:
838  static void LoadNumber(MacroAssembler* masm,
840  Register object,
841  FPURegister dst,
842  Register dst1,
843  Register dst2,
844  Register heap_number_map,
845  Register scratch1,
846  Register scratch2,
847  Label* not_number);
848 };
849 
850 
851 class StringDictionaryLookupStub: public CodeStub {
852  public:
854 
855  explicit StringDictionaryLookupStub(LookupMode mode) : mode_(mode) { }
856 
857  void Generate(MacroAssembler* masm);
858 
859  static void GenerateNegativeLookup(MacroAssembler* masm,
860  Label* miss,
861  Label* done,
862  Register receiver,
863  Register properties,
864  Handle<String> name,
865  Register scratch0);
866 
867  static void GeneratePositiveLookup(MacroAssembler* masm,
868  Label* miss,
869  Label* done,
870  Register elements,
871  Register name,
872  Register r0,
873  Register r1);
874 
875  virtual bool SometimesSetsUpAFrame() { return false; }
876 
877  private:
878  static const int kInlinedProbes = 4;
879  static const int kTotalProbes = 20;
880 
881  static const int kCapacityOffset =
884 
885  static const int kElementsStartOffset =
888 
889  Major MajorKey() { return StringDictionaryLookup; }
890 
891  int MinorKey() {
892  return LookupModeBits::encode(mode_);
893  }
894 
895  class LookupModeBits: public BitField<LookupMode, 0, 1> {};
896 
897  LookupMode mode_;
898 };
899 
900 
901 } } // namespace v8::internal
902 
903 #endif // V8_MIPS_CODE_STUBS_ARM_H_
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
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()
const int kImm16Mask
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)
const RegList kJSCallerSaved
Definition: frames-arm.h:47
RegExpCEntryStub()
static void GenerateCompareFlatAsciiStrings(MacroAssembler *masm, Register left, Register right, Register scratch1, Register scratch2, Register scratch3, Register scratch4)
const Register r2
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 RegList kCallerSavedFPU
Definition: frames-mips.h:89
#define UNREACHABLE()
Definition: checks.h:50
static void GenerateFlatAsciiStringEquals(MacroAssembler *masm, Register left, Register right, Register scratch1, Register scratch2, Register scratch3)
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)
const int kRtShift
static Register FromAllocationIndex(int index)
Definition: assembler-arm.h:82
WriteInt32ToHeapNumberStub(Register the_int, Register the_heap_number, Register scratch, Register scratch2)
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 const int kHeaderSize
Definition: objects.h:2296
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
const int kRsShift
TranscendentalCacheStub(TranscendentalCache::Type type, ArgumentType argument_type)
static void PatchNopIntoBranch(MacroAssembler *masm, int pos)
static bool IsBne(Instr instr)
static void GenerateLookupNumberStringCache(MacroAssembler *masm, Register object, Register result, Register scratch1, Register scratch2, Register scratch3, bool object_is_smi, Label *not_found)
static bool IsBeq(Instr instr)
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)