v8  3.11.10(node0.8.26)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
code-stubs.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_CODE_STUBS_H_
29 #define V8_CODE_STUBS_H_
30 
31 #include "allocation.h"
32 #include "globals.h"
33 #include "codegen.h"
34 
35 namespace v8 {
36 namespace internal {
37 
38 // List of code stubs used on all platforms.
39 #define CODE_STUB_LIST_ALL_PLATFORMS(V) \
40  V(CallFunction) \
41  V(CallConstruct) \
42  V(UnaryOp) \
43  V(BinaryOp) \
44  V(StringAdd) \
45  V(SubString) \
46  V(StringCompare) \
47  V(Compare) \
48  V(CompareIC) \
49  V(MathPow) \
50  V(RecordWrite) \
51  V(StoreBufferOverflow) \
52  V(RegExpExec) \
53  V(TranscendentalCache) \
54  V(Instanceof) \
55  V(ConvertToDouble) \
56  V(WriteInt32ToHeapNumber) \
57  V(StackCheck) \
58  V(Interrupt) \
59  V(FastNewClosure) \
60  V(FastNewContext) \
61  V(FastNewBlockContext) \
62  V(FastCloneShallowArray) \
63  V(FastCloneShallowObject) \
64  V(ToBoolean) \
65  V(ToNumber) \
66  V(ArgumentsAccess) \
67  V(RegExpConstructResult) \
68  V(NumberToString) \
69  V(CEntry) \
70  V(JSEntry) \
71  V(KeyedLoadElement) \
72  V(KeyedStoreElement) \
73  V(DebuggerStatement) \
74  V(StringDictionaryLookup) \
75  V(ElementsTransitionAndStore) \
76  V(StoreArrayLiteralElement)
77 
78 // List of code stubs only used on ARM platforms.
79 #ifdef V8_TARGET_ARCH_ARM
80 #define CODE_STUB_LIST_ARM(V) \
81  V(GetProperty) \
82  V(SetProperty) \
83  V(InvokeBuiltin) \
84  V(RegExpCEntry) \
85  V(DirectCEntry)
86 #else
87 #define CODE_STUB_LIST_ARM(V)
88 #endif
89 
90 // List of code stubs only used on MIPS platforms.
91 #ifdef V8_TARGET_ARCH_MIPS
92 #define CODE_STUB_LIST_MIPS(V) \
93  V(RegExpCEntry) \
94  V(DirectCEntry)
95 #else
96 #define CODE_STUB_LIST_MIPS(V)
97 #endif
98 
99 // Combined list of code stubs.
100 #define CODE_STUB_LIST(V) \
101  CODE_STUB_LIST_ALL_PLATFORMS(V) \
102  CODE_STUB_LIST_ARM(V) \
103  CODE_STUB_LIST_MIPS(V)
104 
105 // Mode to overwrite BinaryExpression values.
108 
109 
110 // Stub is base classes of all stubs.
111 class CodeStub BASE_EMBEDDED {
112  public:
113  enum Major {
114 #define DEF_ENUM(name) name,
116 #undef DEF_ENUM
117  NoCache, // marker for stubs that do custom caching
118  NUMBER_OF_IDS
119  };
120 
121  // Retrieve the code for the stub. Generate the code if needed.
122  Handle<Code> GetCode();
123 
124  static Major MajorKeyFromKey(uint32_t key) {
125  return static_cast<Major>(MajorKeyBits::decode(key));
126  }
127  static int MinorKeyFromKey(uint32_t key) {
128  return MinorKeyBits::decode(key);
129  }
130 
131  // Gets the major key from a code object that is a code stub or binary op IC.
132  static Major GetMajorKey(Code* code_stub) {
133  return static_cast<Major>(code_stub->major_key());
134  }
135 
136  static const char* MajorName(Major major_key, bool allow_unknown_keys);
137 
138  virtual ~CodeStub() {}
139 
141  bool is_pregenerated = IsPregenerated();
142  Code* code = NULL;
143  CHECK(!is_pregenerated || FindCodeInCache(&code));
144  return is_pregenerated;
145  }
146 
147  // See comment above, where Instanceof is defined.
148  virtual bool IsPregenerated() { return false; }
149 
150  static void GenerateStubsAheadOfTime();
151  static void GenerateFPStubs();
152 
153  // Some stubs put untagged junk on the stack that cannot be scanned by the
154  // GC. This means that we must be statically sure that no GC can occur while
155  // they are running. If that is the case they should override this to return
156  // true, which will cause an assertion if we try to call something that can
157  // GC or if we try to put a stack frame on top of the junk, which would not
158  // result in a traversable stack.
159  virtual bool SometimesSetsUpAFrame() { return true; }
160 
161  // Lookup the code in the (possibly custom) cache.
162  bool FindCodeInCache(Code** code_out);
163 
164  protected:
165  static const int kMajorBits = 6;
166  static const int kMinorBits = kBitsPerInt - kSmiTagSize - kMajorBits;
167 
168  private:
169  // Nonvirtual wrapper around the stub-specific Generate function. Call
170  // this function to set up the macro assembler and generate the code.
171  void GenerateCode(MacroAssembler* masm);
172 
173  // Generates the assembler code for the stub.
174  virtual void Generate(MacroAssembler* masm) = 0;
175 
176  // Perform bookkeeping required after code generation when stub code is
177  // initially generated.
178  void RecordCodeGeneration(Code* code, MacroAssembler* masm);
179 
180  // Finish the code object after it has been generated.
181  virtual void FinishCode(Handle<Code> code) { }
182 
183  // Activate newly generated stub. Is called after
184  // registering stub in the stub cache.
185  virtual void Activate(Code* code) { }
186 
187  // Returns information for computing the number key.
188  virtual Major MajorKey() = 0;
189  virtual int MinorKey() = 0;
190 
191  // BinaryOpStub needs to override this.
192  virtual int GetCodeKind();
193 
194  // BinaryOpStub needs to override this.
195  virtual InlineCacheState GetICState() {
196  return UNINITIALIZED;
197  }
198 
199  // Add the code to a specialized cache, specific to an individual
200  // stub type. Please note, this method must add the code object to a
201  // roots object, otherwise we will remove the code during GC.
202  virtual void AddToSpecialCache(Handle<Code> new_object) { }
203 
204  // Find code in a specialized cache, work is delegated to the specific stub.
205  virtual bool FindCodeInSpecialCache(Code** code_out) { return false; }
206 
207  // If a stub uses a special cache override this.
208  virtual bool UseSpecialCache() { return false; }
209 
210  // Returns a name for logging/debugging purposes.
211  SmartArrayPointer<const char> GetName();
212  virtual void PrintName(StringStream* stream);
213 
214  // Returns whether the code generated for this stub needs to be allocated as
215  // a fixed (non-moveable) code object.
216  virtual bool NeedsImmovableCode() { return false; }
217 
218  // Computes the key based on major and minor.
219  uint32_t GetKey() {
220  ASSERT(static_cast<int>(MajorKey()) < NUMBER_OF_IDS);
221  return MinorKeyBits::encode(MinorKey()) |
222  MajorKeyBits::encode(MajorKey());
223  }
224 
225  class MajorKeyBits: public BitField<uint32_t, 0, kMajorBits> {};
226  class MinorKeyBits: public BitField<uint32_t, kMajorBits, kMinorBits> {};
227 
228  friend class BreakPointIterator;
229 };
230 
231 
232 // Helper interface to prepare to/restore after making runtime calls.
234  public:
235  virtual ~RuntimeCallHelper() {}
236 
237  virtual void BeforeCall(MacroAssembler* masm) const = 0;
238 
239  virtual void AfterCall(MacroAssembler* masm) const = 0;
240 
241  protected:
243 
244  private:
245  DISALLOW_COPY_AND_ASSIGN(RuntimeCallHelper);
246 };
247 
248 } } // namespace v8::internal
249 
250 #if V8_TARGET_ARCH_IA32
251 #include "ia32/code-stubs-ia32.h"
252 #elif V8_TARGET_ARCH_X64
253 #include "x64/code-stubs-x64.h"
254 #elif V8_TARGET_ARCH_ARM
255 #include "arm/code-stubs-arm.h"
256 #elif V8_TARGET_ARCH_MIPS
257 #include "mips/code-stubs-mips.h"
258 #else
259 #error Unsupported target architecture.
260 #endif
261 
262 namespace v8 {
263 namespace internal {
264 
265 
266 // RuntimeCallHelper implementation used in stubs: enters/leaves a
267 // newly created internal frame before/after the runtime call.
269  public:
271 
272  virtual void BeforeCall(MacroAssembler* masm) const;
273 
274  virtual void AfterCall(MacroAssembler* masm) const;
275 };
276 
277 
278 // Trivial RuntimeCallHelper implementation.
280  public:
282 
283  virtual void BeforeCall(MacroAssembler* masm) const {}
284 
285  virtual void AfterCall(MacroAssembler* masm) const {}
286 };
287 
288 
289 class StackCheckStub : public CodeStub {
290  public:
292 
293  void Generate(MacroAssembler* masm);
294 
295  private:
296  Major MajorKey() { return StackCheck; }
297  int MinorKey() { return 0; }
298 };
299 
300 
301 class InterruptStub : public CodeStub {
302  public:
304 
305  void Generate(MacroAssembler* masm);
306 
307  private:
308  Major MajorKey() { return Interrupt; }
309  int MinorKey() { return 0; }
310 };
311 
312 
313 class ToNumberStub: public CodeStub {
314  public:
316 
317  void Generate(MacroAssembler* masm);
318 
319  private:
320  Major MajorKey() { return ToNumber; }
321  int MinorKey() { return 0; }
322 };
323 
324 
325 class FastNewClosureStub : public CodeStub {
326  public:
327  explicit FastNewClosureStub(LanguageMode language_mode)
328  : language_mode_(language_mode) { }
329 
330  void Generate(MacroAssembler* masm);
331 
332  private:
333  Major MajorKey() { return FastNewClosure; }
334  int MinorKey() { return language_mode_ == CLASSIC_MODE
336 
337  LanguageMode language_mode_;
338 };
339 
340 
341 class FastNewContextStub : public CodeStub {
342  public:
343  static const int kMaximumSlots = 64;
344 
345  explicit FastNewContextStub(int slots) : slots_(slots) {
346  ASSERT(slots_ > 0 && slots_ <= kMaximumSlots);
347  }
348 
349  void Generate(MacroAssembler* masm);
350 
351  private:
352  int slots_;
353 
354  Major MajorKey() { return FastNewContext; }
355  int MinorKey() { return slots_; }
356 };
357 
358 
359 class FastNewBlockContextStub : public CodeStub {
360  public:
361  static const int kMaximumSlots = 64;
362 
363  explicit FastNewBlockContextStub(int slots) : slots_(slots) {
364  ASSERT(slots_ > 0 && slots_ <= kMaximumSlots);
365  }
366 
367  void Generate(MacroAssembler* masm);
368 
369  private:
370  int slots_;
371 
372  Major MajorKey() { return FastNewBlockContext; }
373  int MinorKey() { return slots_; }
374 };
375 
376 
377 class FastCloneShallowArrayStub : public CodeStub {
378  public:
379  // Maximum length of copied elements array.
380  static const int kMaximumClonedLength = 8;
381 
382  enum Mode {
387  };
388 
389  FastCloneShallowArrayStub(Mode mode, int length)
390  : mode_(mode),
391  length_((mode == COPY_ON_WRITE_ELEMENTS) ? 0 : length) {
392  ASSERT_GE(length_, 0);
394  }
395 
396  void Generate(MacroAssembler* masm);
397 
398  private:
399  Mode mode_;
400  int length_;
401 
402  Major MajorKey() { return FastCloneShallowArray; }
403  int MinorKey() {
404  ASSERT(mode_ == 0 || mode_ == 1 || mode_ == 2 || mode_ == 3);
405  return length_ * 4 + mode_;
406  }
407 };
408 
409 
410 class FastCloneShallowObjectStub : public CodeStub {
411  public:
412  // Maximum number of properties in copied object.
413  static const int kMaximumClonedProperties = 6;
414 
415  explicit FastCloneShallowObjectStub(int length) : length_(length) {
416  ASSERT_GE(length_, 0);
418  }
419 
420  void Generate(MacroAssembler* masm);
421 
422  private:
423  int length_;
424 
425  Major MajorKey() { return FastCloneShallowObject; }
426  int MinorKey() { return length_; }
427 };
428 
429 
430 class InstanceofStub: public CodeStub {
431  public:
432  enum Flags {
433  kNoFlags = 0,
437  };
438 
439  explicit InstanceofStub(Flags flags) : flags_(flags) { }
440 
441  static Register left();
442  static Register right();
443 
444  void Generate(MacroAssembler* masm);
445 
446  private:
447  Major MajorKey() { return Instanceof; }
448  int MinorKey() { return static_cast<int>(flags_); }
449 
450  bool HasArgsInRegisters() const {
451  return (flags_ & kArgsInRegisters) != 0;
452  }
453 
454  bool HasCallSiteInlineCheck() const {
455  return (flags_ & kCallSiteInlineCheck) != 0;
456  }
457 
458  bool ReturnTrueFalseObject() const {
459  return (flags_ & kReturnTrueFalseObject) != 0;
460  }
461 
462  virtual void PrintName(StringStream* stream);
463 
464  Flags flags_;
465 };
466 
467 
468 class MathPowStub: public CodeStub {
469  public:
471 
472  explicit MathPowStub(ExponentType exponent_type)
473  : exponent_type_(exponent_type) { }
474  virtual void Generate(MacroAssembler* masm);
475 
476  private:
477  virtual CodeStub::Major MajorKey() { return MathPow; }
478  virtual int MinorKey() { return exponent_type_; }
479 
480  ExponentType exponent_type_;
481 };
482 
483 
484 class ICCompareStub: public CodeStub {
485  public:
487  : op_(op), state_(state) {
489  }
490 
491  virtual void Generate(MacroAssembler* masm);
492 
493  void set_known_map(Handle<Map> map) { known_map_ = map; }
494 
495  private:
496  class OpField: public BitField<int, 0, 3> { };
497  class StateField: public BitField<int, 3, 5> { };
498 
499  virtual void FinishCode(Handle<Code> code) {
500  code->set_compare_state(state_);
501  code->set_compare_operation(op_);
502  }
503 
504  virtual CodeStub::Major MajorKey() { return CompareIC; }
505  virtual int MinorKey();
506 
507  virtual int GetCodeKind() { return Code::COMPARE_IC; }
508 
509  void GenerateSmis(MacroAssembler* masm);
510  void GenerateHeapNumbers(MacroAssembler* masm);
511  void GenerateSymbols(MacroAssembler* masm);
512  void GenerateStrings(MacroAssembler* masm);
513  void GenerateObjects(MacroAssembler* masm);
514  void GenerateMiss(MacroAssembler* masm);
515  void GenerateKnownObjects(MacroAssembler* masm);
516 
517  bool strict() const { return op_ == Token::EQ_STRICT; }
518  Condition GetCondition() const { return CompareIC::ComputeCondition(op_); }
519 
520  virtual void AddToSpecialCache(Handle<Code> new_object);
521  virtual bool FindCodeInSpecialCache(Code** code_out);
522  virtual bool UseSpecialCache() { return state_ == CompareIC::KNOWN_OBJECTS; }
523 
524  Token::Value op_;
525  CompareIC::State state_;
526  Handle<Map> known_map_;
527 };
528 
529 
530 // Flags that control the compare stub code generation.
536 };
537 
538 
542 };
543 
544 
545 class CompareStub: public CodeStub {
546  public:
548  bool strict,
550  Register lhs,
551  Register rhs) :
552  cc_(cc),
553  strict_(strict),
554  never_nan_nan_((flags & CANT_BOTH_BE_NAN) != 0),
555  include_number_compare_((flags & NO_NUMBER_COMPARE_IN_STUB) == 0),
556  include_smi_compare_((flags & NO_SMI_COMPARE_IN_STUB) == 0),
557  lhs_(lhs),
558  rhs_(rhs) { }
559 
561  bool strict,
563  cc_(cc),
564  strict_(strict),
565  never_nan_nan_((flags & CANT_BOTH_BE_NAN) != 0),
566  include_number_compare_((flags & NO_NUMBER_COMPARE_IN_STUB) == 0),
567  include_smi_compare_((flags & NO_SMI_COMPARE_IN_STUB) == 0),
568  lhs_(no_reg),
569  rhs_(no_reg) { }
570 
571  void Generate(MacroAssembler* masm);
572 
573  private:
574  Condition cc_;
575  bool strict_;
576  // Only used for 'equal' comparisons. Tells the stub that we already know
577  // that at least one side of the comparison is not NaN. This allows the
578  // stub to use object identity in the positive case. We ignore it when
579  // generating the minor key for other comparisons to avoid creating more
580  // stubs.
581  bool never_nan_nan_;
582  // Do generate the number comparison code in the stub. Stubs without number
583  // comparison code is used when the number comparison has been inlined, and
584  // the stub will be called if one of the operands is not a number.
585  bool include_number_compare_;
586 
587  // Generate the comparison code for two smi operands in the stub.
588  bool include_smi_compare_;
589 
590  // Register holding the left hand side of the comparison if the stub gives
591  // a choice, no_reg otherwise.
592 
593  Register lhs_;
594  // Register holding the right hand side of the comparison if the stub gives
595  // a choice, no_reg otherwise.
596  Register rhs_;
597 
598  // Encoding of the minor key in 16 bits.
599  class StrictField: public BitField<bool, 0, 1> {};
600  class NeverNanNanField: public BitField<bool, 1, 1> {};
601  class IncludeNumberCompareField: public BitField<bool, 2, 1> {};
602  class IncludeSmiCompareField: public BitField<bool, 3, 1> {};
603  class RegisterField: public BitField<bool, 4, 1> {};
604  class ConditionField: public BitField<int, 5, 11> {};
605 
606  Major MajorKey() { return Compare; }
607 
608  int MinorKey();
609 
610  virtual int GetCodeKind() { return Code::COMPARE_IC; }
611  virtual void FinishCode(Handle<Code> code) {
612  code->set_compare_state(CompareIC::GENERIC);
613  }
614 
615  // Branch to the label if the given object isn't a symbol.
616  void BranchIfNonSymbol(MacroAssembler* masm,
617  Label* label,
618  Register object,
619  Register scratch);
620 
621  // Unfortunately you have to run without snapshots to see most of these
622  // names in the profile since most compare stubs end up in the snapshot.
623  virtual void PrintName(StringStream* stream);
624 };
625 
626 
627 class CEntryStub : public CodeStub {
628  public:
629  explicit CEntryStub(int result_size,
630  SaveFPRegsMode save_doubles = kDontSaveFPRegs)
631  : result_size_(result_size), save_doubles_(save_doubles) { }
632 
633  void Generate(MacroAssembler* masm);
634 
635  // The version of this stub that doesn't save doubles is generated ahead of
636  // time, so it's OK to call it from other stubs that can't cope with GC during
637  // their code generation. On machines that always have gp registers (x64) we
638  // can generate both variants ahead of time.
639  virtual bool IsPregenerated();
640  static void GenerateAheadOfTime();
641 
642  private:
643  void GenerateCore(MacroAssembler* masm,
644  Label* throw_normal_exception,
645  Label* throw_termination_exception,
646  Label* throw_out_of_memory_exception,
647  bool do_gc,
648  bool always_allocate_scope);
649 
650  // Number of pointers/values returned.
651  const int result_size_;
652  SaveFPRegsMode save_doubles_;
653 
654  Major MajorKey() { return CEntry; }
655  int MinorKey();
656 
657  bool NeedsImmovableCode();
658 };
659 
660 
661 class JSEntryStub : public CodeStub {
662  public:
664 
665  void Generate(MacroAssembler* masm) { GenerateBody(masm, false); }
666 
667  protected:
668  void GenerateBody(MacroAssembler* masm, bool is_construct);
669 
670  private:
671  Major MajorKey() { return JSEntry; }
672  int MinorKey() { return 0; }
673 
674  virtual void FinishCode(Handle<Code> code);
675 
676  int handler_offset_;
677 };
678 
679 
681  public:
683 
684  void Generate(MacroAssembler* masm) { GenerateBody(masm, true); }
685 
686  private:
687  int MinorKey() { return 1; }
688 
689  virtual void PrintName(StringStream* stream) {
690  stream->Add("JSConstructEntryStub");
691  }
692 };
693 
694 
695 class ArgumentsAccessStub: public CodeStub {
696  public:
697  enum Type {
702  };
703 
704  explicit ArgumentsAccessStub(Type type) : type_(type) { }
705 
706  private:
707  Type type_;
708 
709  Major MajorKey() { return ArgumentsAccess; }
710  int MinorKey() { return type_; }
711 
712  void Generate(MacroAssembler* masm);
713  void GenerateReadElement(MacroAssembler* masm);
714  void GenerateNewStrict(MacroAssembler* masm);
715  void GenerateNewNonStrictFast(MacroAssembler* masm);
716  void GenerateNewNonStrictSlow(MacroAssembler* masm);
717 
718  virtual void PrintName(StringStream* stream);
719 };
720 
721 
722 class RegExpExecStub: public CodeStub {
723  public:
725 
726  private:
727  Major MajorKey() { return RegExpExec; }
728  int MinorKey() { return 0; }
729 
730  void Generate(MacroAssembler* masm);
731 };
732 
733 
734 class RegExpConstructResultStub: public CodeStub {
735  public:
737 
738  private:
739  Major MajorKey() { return RegExpConstructResult; }
740  int MinorKey() { return 0; }
741 
742  void Generate(MacroAssembler* masm);
743 };
744 
745 
746 class CallFunctionStub: public CodeStub {
747  public:
749  : argc_(argc), flags_(flags) { }
750 
751  void Generate(MacroAssembler* masm);
752 
753  virtual void FinishCode(Handle<Code> code) {
754  code->set_has_function_cache(RecordCallTarget());
755  }
756 
757  static int ExtractArgcFromMinorKey(int minor_key) {
758  return ArgcBits::decode(minor_key);
759  }
760 
761  private:
762  int argc_;
763  CallFunctionFlags flags_;
764 
765  virtual void PrintName(StringStream* stream);
766 
767  // Minor key encoding in 32 bits with Bitfield <Type, shift, size>.
768  class FlagBits: public BitField<CallFunctionFlags, 0, 2> {};
769  class ArgcBits: public BitField<unsigned, 2, 32 - 2> {};
770 
771  Major MajorKey() { return CallFunction; }
772  int MinorKey() {
773  // Encode the parameters in a unique 32 bit value.
774  return FlagBits::encode(flags_) | ArgcBits::encode(argc_);
775  }
776 
777  bool ReceiverMightBeImplicit() {
778  return (flags_ & RECEIVER_MIGHT_BE_IMPLICIT) != 0;
779  }
780 
781  bool RecordCallTarget() {
782  return (flags_ & RECORD_CALL_TARGET) != 0;
783  }
784 };
785 
786 
787 class CallConstructStub: public CodeStub {
788  public:
789  explicit CallConstructStub(CallFunctionFlags flags) : flags_(flags) {}
790 
791  void Generate(MacroAssembler* masm);
792 
793  virtual void FinishCode(Handle<Code> code) {
794  code->set_has_function_cache(RecordCallTarget());
795  }
796 
797  private:
798  CallFunctionFlags flags_;
799 
800  virtual void PrintName(StringStream* stream);
801 
802  Major MajorKey() { return CallConstruct; }
803  int MinorKey() { return flags_; }
804 
805  bool RecordCallTarget() {
806  return (flags_ & RECORD_CALL_TARGET) != 0;
807  }
808 };
809 
810 
812  // Accepts smis or heap numbers.
814 
815  // Accepts smis or heap numbers that are valid array indices
816  // (ECMA-262 15.4). Invalid indices are reported as being out of
817  // range.
819 };
820 
821 
822 // Generates code implementing String.prototype.charCodeAt.
823 //
824 // Only supports the case when the receiver is a string and the index
825 // is a number (smi or heap number) that is a valid index into the
826 // string. Additional index constraints are specified by the
827 // flags. Otherwise, bails out to the provided labels.
828 //
829 // Register usage: |object| may be changed to another string in a way
830 // that doesn't affect charCodeAt/charAt semantics, |index| is
831 // preserved, |scratch| and |result| are clobbered.
833  public:
835  Register index,
836  Register result,
837  Label* receiver_not_string,
838  Label* index_not_number,
839  Label* index_out_of_range,
840  StringIndexFlags index_flags)
841  : object_(object),
842  index_(index),
843  result_(result),
844  receiver_not_string_(receiver_not_string),
845  index_not_number_(index_not_number),
846  index_out_of_range_(index_out_of_range),
847  index_flags_(index_flags) {
848  ASSERT(!result_.is(object_));
849  ASSERT(!result_.is(index_));
850  }
851 
852  // Generates the fast case code. On the fallthrough path |result|
853  // register contains the result.
854  void GenerateFast(MacroAssembler* masm);
855 
856  // Generates the slow case code. Must not be naturally
857  // reachable. Expected to be put after a ret instruction (e.g., in
858  // deferred code). Always jumps back to the fast case.
859  void GenerateSlow(MacroAssembler* masm,
860  const RuntimeCallHelper& call_helper);
861 
862  private:
863  Register object_;
864  Register index_;
865  Register result_;
866 
867  Label* receiver_not_string_;
868  Label* index_not_number_;
869  Label* index_out_of_range_;
870 
871  StringIndexFlags index_flags_;
872 
873  Label call_runtime_;
874  Label index_not_smi_;
875  Label got_smi_index_;
876  Label exit_;
877 
878  DISALLOW_COPY_AND_ASSIGN(StringCharCodeAtGenerator);
879 };
880 
881 
882 // Generates code for creating a one-char string from a char code.
884  public:
886  Register result)
887  : code_(code),
888  result_(result) {
889  ASSERT(!code_.is(result_));
890  }
891 
892  // Generates the fast case code. On the fallthrough path |result|
893  // register contains the result.
894  void GenerateFast(MacroAssembler* masm);
895 
896  // Generates the slow case code. Must not be naturally
897  // reachable. Expected to be put after a ret instruction (e.g., in
898  // deferred code). Always jumps back to the fast case.
899  void GenerateSlow(MacroAssembler* masm,
900  const RuntimeCallHelper& call_helper);
901 
902  private:
903  Register code_;
904  Register result_;
905 
906  Label slow_case_;
907  Label exit_;
908 
909  DISALLOW_COPY_AND_ASSIGN(StringCharFromCodeGenerator);
910 };
911 
912 
913 // Generates code implementing String.prototype.charAt.
914 //
915 // Only supports the case when the receiver is a string and the index
916 // is a number (smi or heap number) that is a valid index into the
917 // string. Additional index constraints are specified by the
918 // flags. Otherwise, bails out to the provided labels.
919 //
920 // Register usage: |object| may be changed to another string in a way
921 // that doesn't affect charCodeAt/charAt semantics, |index| is
922 // preserved, |scratch1|, |scratch2|, and |result| are clobbered.
924  public:
926  Register index,
927  Register scratch,
928  Register result,
929  Label* receiver_not_string,
930  Label* index_not_number,
931  Label* index_out_of_range,
932  StringIndexFlags index_flags)
933  : char_code_at_generator_(object,
934  index,
935  scratch,
936  receiver_not_string,
937  index_not_number,
938  index_out_of_range,
939  index_flags),
940  char_from_code_generator_(scratch, result) {}
941 
942  // Generates the fast case code. On the fallthrough path |result|
943  // register contains the result.
944  void GenerateFast(MacroAssembler* masm);
945 
946  // Generates the slow case code. Must not be naturally
947  // reachable. Expected to be put after a ret instruction (e.g., in
948  // deferred code). Always jumps back to the fast case.
949  void GenerateSlow(MacroAssembler* masm,
950  const RuntimeCallHelper& call_helper);
951 
952  private:
953  StringCharCodeAtGenerator char_code_at_generator_;
954  StringCharFromCodeGenerator char_from_code_generator_;
955 
956  DISALLOW_COPY_AND_ASSIGN(StringCharAtGenerator);
957 };
958 
959 
961  public:
963  : masm_(masm), previous_allow_(masm->allow_stub_calls()) {
964  masm_->set_allow_stub_calls(allow);
965  }
967  masm_->set_allow_stub_calls(previous_allow_);
968  }
969 
970  private:
971  MacroAssembler* masm_;
972  bool previous_allow_;
973 
974  DISALLOW_COPY_AND_ASSIGN(AllowStubCallsScope);
975 };
976 
977 
978 class KeyedLoadElementStub : public CodeStub {
979  public:
980  explicit KeyedLoadElementStub(ElementsKind elements_kind)
981  : elements_kind_(elements_kind)
982  { }
983 
984  Major MajorKey() { return KeyedLoadElement; }
985  int MinorKey() { return elements_kind_; }
986 
987  void Generate(MacroAssembler* masm);
988 
989  private:
990  ElementsKind elements_kind_;
991 
992  DISALLOW_COPY_AND_ASSIGN(KeyedLoadElementStub);
993 };
994 
995 
996 class KeyedStoreElementStub : public CodeStub {
997  public:
998  KeyedStoreElementStub(bool is_js_array,
999  ElementsKind elements_kind,
1000  KeyedAccessGrowMode grow_mode)
1001  : is_js_array_(is_js_array),
1002  elements_kind_(elements_kind),
1003  grow_mode_(grow_mode) { }
1004 
1005  Major MajorKey() { return KeyedStoreElement; }
1006  int MinorKey() {
1007  return ElementsKindBits::encode(elements_kind_) |
1008  IsJSArrayBits::encode(is_js_array_) |
1009  GrowModeBits::encode(grow_mode_);
1010  }
1011 
1012  void Generate(MacroAssembler* masm);
1013 
1014  private:
1015  class ElementsKindBits: public BitField<ElementsKind, 0, 8> {};
1016  class GrowModeBits: public BitField<KeyedAccessGrowMode, 8, 1> {};
1017  class IsJSArrayBits: public BitField<bool, 9, 1> {};
1018 
1019  bool is_js_array_;
1020  ElementsKind elements_kind_;
1021  KeyedAccessGrowMode grow_mode_;
1022 
1023  DISALLOW_COPY_AND_ASSIGN(KeyedStoreElementStub);
1024 };
1025 
1026 
1027 class ToBooleanStub: public CodeStub {
1028  public:
1029  enum Type {
1038  };
1039 
1040  // At most 8 different types can be distinguished, because the Code object
1041  // only has room for a single byte to hold a set of these types. :-P
1043 
1044  class Types {
1045  public:
1046  Types() {}
1047  explicit Types(byte bits) : set_(bits) {}
1048 
1049  bool IsEmpty() const { return set_.IsEmpty(); }
1050  bool Contains(Type type) const { return set_.Contains(type); }
1051  void Add(Type type) { set_.Add(type); }
1052  byte ToByte() const { return set_.ToIntegral(); }
1053  void Print(StringStream* stream) const;
1054  void TraceTransition(Types to) const;
1055  bool Record(Handle<Object> object);
1056  bool NeedsMap() const;
1057  bool CanBeUndetectable() const;
1058 
1059  private:
1060  EnumSet<Type, byte> set_;
1061  };
1062 
1063  static Types no_types() { return Types(); }
1064  static Types all_types() { return Types((1 << NUMBER_OF_TYPES) - 1); }
1065 
1066  explicit ToBooleanStub(Register tos, Types types = Types())
1067  : tos_(tos), types_(types) { }
1068 
1069  void Generate(MacroAssembler* masm);
1070  virtual int GetCodeKind() { return Code::TO_BOOLEAN_IC; }
1071  virtual void PrintName(StringStream* stream);
1072 
1073  virtual bool SometimesSetsUpAFrame() { return false; }
1074 
1075  private:
1076  Major MajorKey() { return ToBoolean; }
1077  int MinorKey() { return (tos_.code() << NUMBER_OF_TYPES) | types_.ToByte(); }
1078 
1079  virtual void FinishCode(Handle<Code> code) {
1080  code->set_to_boolean_state(types_.ToByte());
1081  }
1082 
1083  void CheckOddball(MacroAssembler* masm,
1084  Type type,
1085  Heap::RootListIndex value,
1086  bool result);
1087  void GenerateTypeTransition(MacroAssembler* masm);
1088 
1089  Register tos_;
1090  Types types_;
1091 };
1092 
1093 
1094 class ElementsTransitionAndStoreStub : public CodeStub {
1095  public:
1097  ElementsKind to,
1098  bool is_jsarray,
1099  StrictModeFlag strict_mode,
1100  KeyedAccessGrowMode grow_mode)
1101  : from_(from),
1102  to_(to),
1103  is_jsarray_(is_jsarray),
1104  strict_mode_(strict_mode),
1105  grow_mode_(grow_mode) {}
1106 
1107  private:
1108  class FromBits: public BitField<ElementsKind, 0, 8> {};
1109  class ToBits: public BitField<ElementsKind, 8, 8> {};
1110  class IsJSArrayBits: public BitField<bool, 16, 1> {};
1111  class StrictModeBits: public BitField<StrictModeFlag, 17, 1> {};
1112  class GrowModeBits: public BitField<KeyedAccessGrowMode, 18, 1> {};
1113 
1114  Major MajorKey() { return ElementsTransitionAndStore; }
1115  int MinorKey() {
1116  return FromBits::encode(from_) |
1117  ToBits::encode(to_) |
1118  IsJSArrayBits::encode(is_jsarray_) |
1119  StrictModeBits::encode(strict_mode_) |
1120  GrowModeBits::encode(grow_mode_);
1121  }
1122 
1123  void Generate(MacroAssembler* masm);
1124 
1125  ElementsKind from_;
1126  ElementsKind to_;
1127  bool is_jsarray_;
1128  StrictModeFlag strict_mode_;
1129  KeyedAccessGrowMode grow_mode_;
1130 
1131  DISALLOW_COPY_AND_ASSIGN(ElementsTransitionAndStoreStub);
1132 };
1133 
1134 
1135 class StoreArrayLiteralElementStub : public CodeStub {
1136  public:
1138 
1139  private:
1140  Major MajorKey() { return StoreArrayLiteralElement; }
1141  int MinorKey() { return 0; }
1142 
1143  void Generate(MacroAssembler* masm);
1144 
1145  DISALLOW_COPY_AND_ASSIGN(StoreArrayLiteralElementStub);
1146 };
1147 
1148 } } // namespace v8::internal
1149 
1150 #endif // V8_CODE_STUBS_H_
MathPowStub(ExponentType exponent_type)
Definition: code-stubs.h:472
void GenerateFast(MacroAssembler *masm)
void GenerateSlow(MacroAssembler *masm, const RuntimeCallHelper &call_helper)
virtual void FinishCode(Handle< Code > code)
Definition: code-stubs.h:753
void GenerateFast(MacroAssembler *masm)
virtual void AfterCall(MacroAssembler *masm) const
Definition: code-stubs.h:285
void GenerateSlow(MacroAssembler *masm, const RuntimeCallHelper &call_helper)
CallFunctionStub(int argc, CallFunctionFlags flags)
Definition: code-stubs.h:748
virtual void FinishCode(Handle< Code > code)
Definition: code-stubs.h:793
void Generate(MacroAssembler *masm)
StringCharFromCodeGenerator(Register code, Register result)
Definition: code-stubs.h:885
static int ExtractArgcFromMinorKey(int minor_key)
Definition: code-stubs.h:757
static bool IsCompareOp(Value op)
Definition: token.h:214
virtual void PrintName(StringStream *stream)
Definition: code-stubs.cc:358
void set_known_map(Handle< Map > map)
Definition: code-stubs.h:493
Flag flags[]
Definition: flags.cc:1467
bool Record(Handle< Object > object)
Definition: code-stubs.cc:391
JSEntryStub()
Definition: code-stubs.h:663
CompareStub(Condition cc, bool strict, CompareFlags flags, Register lhs, Register rhs)
Definition: code-stubs.h:547
void Generate(MacroAssembler *masm)
Definition: code-stubs.h:684
void Generate(MacroAssembler *masm)
virtual bool IsPregenerated()
void Generate(MacroAssembler *masm)
#define ASSERT(condition)
Definition: checks.h:270
#define ASSERT_GE(v1, v2)
Definition: checks.h:273
virtual void AfterCall(MacroAssembler *masm) const
bool IsEmpty() const
Definition: utils.h:958
static const int kMaximumSlots
Definition: code-stubs.h:343
#define CHECK(condition)
Definition: checks.h:56
void Generate(MacroAssembler *masm)
virtual bool SometimesSetsUpAFrame()
Definition: code-stubs.h:1073
void Generate(MacroAssembler *masm)
Definition: code-stubs.h:665
uint8_t byte
Definition: globals.h:171
KeyedStoreElementStub(bool is_js_array, ElementsKind elements_kind, KeyedAccessGrowMode grow_mode)
Definition: code-stubs.h:998
STATIC_ASSERT(NUMBER_OF_TYPES<=8)
virtual void AfterCall(MacroAssembler *masm) const =0
virtual bool IsPregenerated()
Definition: code-stubs.h:148
static Condition ComputeCondition(Token::Value op)
CallConstructStub(CallFunctionFlags flags)
Definition: code-stubs.h:789
void Generate(MacroAssembler *masm)
virtual void BeforeCall(MacroAssembler *masm) const =0
StringCharCodeAtGenerator(Register object, Register index, Register result, Label *receiver_not_string, Label *index_not_number, Label *index_out_of_range, StringIndexFlags index_flags)
Definition: code-stubs.h:834
StringCharAtGenerator(Register object, Register index, Register scratch, Register result, Label *receiver_not_string, Label *index_not_number, Label *index_out_of_range, StringIndexFlags index_flags)
Definition: code-stubs.h:925
virtual void BeforeCall(MacroAssembler *masm) const
Definition: code-stubs.h:283
int Compare(const T &a, const T &b)
Definition: utils.h:156
ToBooleanStub(Register tos, Types types=Types())
Definition: code-stubs.h:1066
void Generate(MacroAssembler *masm)
#define ASSERT_LE(v1, v2)
Definition: checks.h:275
ElementsTransitionAndStoreStub(ElementsKind from, ElementsKind to, bool is_jsarray, StrictModeFlag strict_mode, KeyedAccessGrowMode grow_mode)
Definition: code-stubs.h:1096
AllowStubCallsScope(MacroAssembler *masm, bool allow)
Definition: code-stubs.h:962
Definition: code-stubs.h:680
#define BASE_EMBEDDED
Definition: allocation.h:68
void Generate(MacroAssembler *masm)
const int kBitsPerInt
Definition: globals.h:254
void GenerateSlow(MacroAssembler *masm, const RuntimeCallHelper &call_helper)
virtual void Generate(MacroAssembler *masm)
virtual bool SometimesSetsUpAFrame()
Definition: code-stubs.h:159
void Generate(MacroAssembler *masm)
int ToNumber(Register reg)
bool is(Register reg) const
#define DEF_ENUM(name)
Definition: code-stubs.h:114
static Major GetMajorKey(Code *code_stub)
Definition: code-stubs.h:132
void Generate(MacroAssembler *masm)
bool Contains(E element) const
Definition: utils.h:959
T ToIntegral() const
Definition: utils.h:969
const int kSmiTagSize
Definition: v8.h:3854
void GenerateBody(MacroAssembler *masm, bool is_construct)
FastNewClosureStub(LanguageMode language_mode)
Definition: code-stubs.h:327
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 trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt 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 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
Definition: flags.cc:274
static void GenerateAheadOfTime()
void Generate(MacroAssembler *masm)
CompareStub(Condition cc, bool strict, CompareFlags flags)
Definition: code-stubs.h:560
void Generate(MacroAssembler *masm)
Definition: code-stubs.cc:295
void GenerateFast(MacroAssembler *masm)
void TraceTransition(Types to) const
Definition: code-stubs.cc:376
Definition: code-stubs.h:627
FastCloneShallowArrayStub(Mode mode, int length)
Definition: code-stubs.h:389
const Register no_reg
bool Contains(Type type) const
Definition: code-stubs.h:1050
KeyedLoadElementStub(ElementsKind elements_kind)
Definition: code-stubs.h:980
static Major MajorKeyFromKey(uint32_t key)
Definition: code-stubs.h:124
virtual void Generate(MacroAssembler *masm)
Definition: code-stubs.cc:201
virtual void BeforeCall(MacroAssembler *masm) const
KeyedAccessGrowMode
Definition: objects.h:141
Definition: code-stubs.h:661
void Add(E element)
Definition: utils.h:963
#define CODE_STUB_LIST(V)
Definition: code-stubs.h:100
void Generate(MacroAssembler *masm)
void Print(StringStream *stream) const
Definition: code-stubs.cc:364
void Generate(MacroAssembler *masm)
CEntryStub(int result_size, SaveFPRegsMode save_doubles=kDontSaveFPRegs)
Definition: code-stubs.h:629
void Generate(MacroAssembler *masm)
Definition: code-stubs.cc:262
void Generate(MacroAssembler *masm)
FlagType type() const
Definition: flags.cc:1358
JSConstructEntryStub()
Definition: code-stubs.h:682
ICCompareStub(Token::Value op, CompareIC::State state)
Definition: code-stubs.h:486
static int MinorKeyFromKey(uint32_t key)
Definition: code-stubs.h:127
void Generate(MacroAssembler *masm)