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
stub-cache.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_STUB_CACHE_H_
29 #define V8_STUB_CACHE_H_
30 
31 #include "allocation.h"
32 #include "arguments.h"
33 #include "ic-inl.h"
34 #include "macro-assembler.h"
35 #include "objects.h"
36 #include "zone-inl.h"
37 
38 namespace v8 {
39 namespace internal {
40 
41 
42 // The stub cache is used for megamorphic calls and property accesses.
43 // It maps (map, name, type)->Code*
44 
45 // The design of the table uses the inline cache stubs used for
46 // mono-morphic calls. The beauty of this, we do not have to
47 // invalidate the cache whenever a prototype map is changed. The stub
48 // validates the map chain as in the mono-morphic case.
49 
50 class SmallMapList;
51 class StubCache;
52 
53 
55  public:
56  Address address() const { return address_; }
57 
58  private:
59  explicit SCTableReference(Address address) : address_(address) {}
60 
61  Address address_;
62 
63  friend class StubCache;
64 };
65 
66 
67 class StubCache {
68  public:
69  struct Entry {
72  Map* map;
73  };
74 
75  void Initialize();
76 
77 
78  // Computes the right stub matching. Inserts the result in the
79  // cache before returning. This might compile a stub if needed.
81  Handle<JSObject> receiver);
82 
84  Handle<JSObject> receiver,
85  Handle<JSObject> holder,
86  int field_index);
87 
89  Handle<JSObject> receiver,
90  Handle<JSObject> holder,
91  Handle<AccessorInfo> callback);
92 
94  Handle<JSObject> receiver,
95  Handle<JSObject> holder,
96  Handle<JSFunction> getter);
97 
99  Handle<JSObject> receiver,
100  Handle<JSObject> holder,
101  Handle<JSFunction> value);
102 
104  Handle<JSObject> receiver,
105  Handle<JSObject> holder);
106 
108 
110  Handle<JSObject> receiver,
111  Handle<GlobalObject> holder,
113  bool is_dont_delete);
114 
115  // ---
116 
118  Handle<JSObject> receiver,
119  Handle<JSObject> holder,
120  int field_index);
121 
123  Handle<JSObject> receiver,
124  Handle<JSObject> holder,
125  Handle<AccessorInfo> callback);
126 
128  Handle<JSObject> receiver,
129  Handle<JSObject> holder,
130  Handle<JSFunction> value);
131 
133  Handle<JSObject> receiver,
134  Handle<JSObject> holder);
135 
137  Handle<JSArray> receiver);
138 
140  Handle<String> receiver);
141 
143  Handle<JSFunction> receiver);
144 
145  // ---
146 
148  Handle<JSObject> receiver,
149  int field_index,
150  Handle<Map> transition,
151  StrictModeFlag strict_mode);
152 
154 
156  Handle<GlobalObject> receiver,
158  StrictModeFlag strict_mode);
159 
161  Handle<JSObject> receiver,
162  Handle<JSObject> holder,
163  Handle<AccessorInfo> callback,
164  StrictModeFlag strict_mode);
165 
167  Handle<JSObject> receiver,
168  Handle<JSObject> holder,
169  Handle<JSFunction> setter,
170  StrictModeFlag strict_mode);
171 
173  Handle<JSObject> receiver,
174  StrictModeFlag strict_mode);
175 
176  // ---
177 
179  Handle<JSObject> receiver,
180  int field_index,
181  Handle<Map> transition,
182  StrictModeFlag strict_mode);
183 
185  KeyedIC::StubKind stub_kind,
186  StrictModeFlag strict_mode);
187 
188  // ---
189 
191  Code::Kind,
192  Code::ExtraICState extra_state,
193  Handle<String> name,
194  Handle<Object> object,
195  Handle<JSObject> holder,
196  int index);
197 
199  Code::Kind,
200  Code::ExtraICState extra_state,
201  Handle<String> name,
202  Handle<Object> object,
203  Handle<JSObject> holder,
204  Handle<JSFunction> function);
205 
207  Code::Kind,
208  Code::ExtraICState extra_state,
209  Handle<String> name,
210  Handle<Object> object,
211  Handle<JSObject> holder);
212 
214  Code::Kind,
215  Code::ExtraICState extra_state,
216  Handle<String> name,
217  Handle<JSObject> receiver,
218  Handle<GlobalObject> holder,
220  Handle<JSFunction> function);
221 
222  // ---
223 
224  Handle<Code> ComputeCallInitialize(int argc, RelocInfo::Mode mode);
225 
227 
229  Code::Kind kind,
230  Code::ExtraICState extra_state);
231 
233  Code::Kind kind,
234  Code::ExtraICState state);
235 
237 
239  Code::Kind kind,
240  Code::ExtraICState state);
241 
242  Handle<Code> ComputeCallMiss(int argc,
243  Code::Kind kind,
244  Code::ExtraICState state);
245 
246  // Finds the Code object stored in the Heap::non_monomorphic_cache().
247  Code* FindCallInitialize(int argc, RelocInfo::Mode mode, Code::Kind kind);
248 
249 #ifdef ENABLE_DEBUGGER_SUPPORT
250  Handle<Code> ComputeCallDebugBreak(int argc, Code::Kind kind);
251 
252  Handle<Code> ComputeCallDebugPrepareStepIn(int argc, Code::Kind kind);
253 #endif
254 
255  // Update cache for entry hash(name, map).
256  Code* Set(String* name, Map* map, Code* code);
257 
258  // Clear the lookup table (@ mark compact collection).
259  void Clear();
260 
261  // Collect all maps that match the name and flags.
262  void CollectMatchingMaps(SmallMapList* types,
263  String* name,
265  Handle<Context> native_context,
266  Zone* zone);
267 
268  // Generate code for probing the stub cache table.
269  // Arguments extra, extra2 and extra3 may be used to pass additional scratch
270  // registers. Set to no_reg if not needed.
271  void GenerateProbe(MacroAssembler* masm,
273  Register receiver,
274  Register name,
275  Register scratch,
276  Register extra,
277  Register extra2 = no_reg,
278  Register extra3 = no_reg);
279 
280  enum Table {
283  };
284 
285 
287  return SCTableReference(
288  reinterpret_cast<Address>(&first_entry(table)->key));
289  }
290 
291 
293  return SCTableReference(
294  reinterpret_cast<Address>(&first_entry(table)->map));
295  }
296 
297 
299  return SCTableReference(
300  reinterpret_cast<Address>(&first_entry(table)->value));
301  }
302 
303 
305  switch (table) {
306  case StubCache::kPrimary: return StubCache::primary_;
307  case StubCache::kSecondary: return StubCache::secondary_;
308  }
309  UNREACHABLE();
310  return NULL;
311  }
312 
313  Isolate* isolate() { return isolate_; }
314  Heap* heap() { return isolate()->heap(); }
315  Factory* factory() { return isolate()->factory(); }
316 
317  private:
318  StubCache(Isolate* isolate, Zone* zone);
319 
321  RelocInfo::Mode mode,
322  Code::Kind kind);
323 
324  // The stub cache has a primary and secondary level. The two levels have
325  // different hashing algorithms in order to avoid simultaneous collisions
326  // in both caches. Unlike a probing strategy (quadratic or otherwise) the
327  // update strategy on updates is fairly clear and simple: Any existing entry
328  // in the primary cache is moved to the secondary cache, and secondary cache
329  // entries are overwritten.
330 
331  // Hash algorithm for the primary table. This algorithm is replicated in
332  // assembler for every architecture. Returns an index into the table that
333  // is scaled by 1 << kHeapObjectTagSize.
334  static int PrimaryOffset(String* name, Code::Flags flags, Map* map) {
335  // This works well because the heap object tag size and the hash
336  // shift are equal. Shifting down the length field to get the
337  // hash code would effectively throw away two bits of the hash
338  // code.
340  // Compute the hash of the name (use entire hash field).
341  ASSERT(name->HasHashCode());
342  uint32_t field = name->hash_field();
343  // Using only the low bits in 64-bit mode is unlikely to increase the
344  // risk of collision even if the heap is spread over an area larger than
345  // 4Gb (and not at all if it isn't).
346  uint32_t map_low32bits =
347  static_cast<uint32_t>(reinterpret_cast<uintptr_t>(map));
348  // We always set the in_loop bit to zero when generating the lookup code
349  // so do it here too so the hash codes match.
350  uint32_t iflags =
351  (static_cast<uint32_t>(flags) & ~Code::kFlagsNotUsedInLookup);
352  // Base the offset on a simple combination of name, flags, and map.
353  uint32_t key = (map_low32bits + field) ^ iflags;
354  return key & ((kPrimaryTableSize - 1) << kHeapObjectTagSize);
355  }
356 
357  // Hash algorithm for the secondary table. This algorithm is replicated in
358  // assembler for every architecture. Returns an index into the table that
359  // is scaled by 1 << kHeapObjectTagSize.
360  static int SecondaryOffset(String* name, Code::Flags flags, int seed) {
361  // Use the seed from the primary cache in the secondary cache.
362  uint32_t string_low32bits =
363  static_cast<uint32_t>(reinterpret_cast<uintptr_t>(name));
364  // We always set the in_loop bit to zero when generating the lookup code
365  // so do it here too so the hash codes match.
366  uint32_t iflags =
367  (static_cast<uint32_t>(flags) & ~Code::kFlagsNotUsedInLookup);
368  uint32_t key = (seed - string_low32bits) + iflags;
369  return key & ((kSecondaryTableSize - 1) << kHeapObjectTagSize);
370  }
371 
372  // Compute the entry for a given offset in exactly the same way as
373  // we do in generated code. We generate an hash code that already
374  // ends in String::kHashShift 0s. Then we multiply it so it is a multiple
375  // of sizeof(Entry). This makes it easier to avoid making mistakes
376  // in the hashed offset computations.
377  static Entry* entry(Entry* table, int offset) {
378  const int multiplier = sizeof(*table) >> String::kHashShift;
379  return reinterpret_cast<Entry*>(
380  reinterpret_cast<Address>(table) + offset * multiplier);
381  }
382 
383  static const int kPrimaryTableBits = 11;
384  static const int kPrimaryTableSize = (1 << kPrimaryTableBits);
385  static const int kSecondaryTableBits = 9;
386  static const int kSecondaryTableSize = (1 << kSecondaryTableBits);
387 
388  Entry primary_[kPrimaryTableSize];
389  Entry secondary_[kSecondaryTableSize];
390  Isolate* isolate_;
391 
392  friend class Isolate;
393  friend class SCTableReference;
394 
396 };
397 
398 
399 // ------------------------------------------------------------------------
400 
401 
402 // Support functions for IC stubs for callbacks.
403 DECLARE_RUNTIME_FUNCTION(MaybeObject*, LoadCallbackProperty);
404 DECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreCallbackProperty);
405 
406 
407 // Support functions for IC stubs for interceptors.
408 DECLARE_RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorOnly);
409 DECLARE_RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForLoad);
410 DECLARE_RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForCall);
411 DECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty);
412 DECLARE_RUNTIME_FUNCTION(MaybeObject*, CallInterceptorProperty);
413 DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor);
414 
415 
416 // The stub compilers compile stubs for the stub cache.
417 class StubCompiler BASE_EMBEDDED {
418  public:
419  explicit StubCompiler(Isolate* isolate)
420  : isolate_(isolate), masm_(isolate, NULL, 256), failure_(NULL) { }
421 
422  // Functions to compile either CallIC or KeyedCallIC. The specific kind
423  // is extracted from the code flags.
424  Handle<Code> CompileCallInitialize(Code::Flags flags);
425  Handle<Code> CompileCallPreMonomorphic(Code::Flags flags);
426  Handle<Code> CompileCallNormal(Code::Flags flags);
427  Handle<Code> CompileCallMegamorphic(Code::Flags flags);
428  Handle<Code> CompileCallArguments(Code::Flags flags);
429  Handle<Code> CompileCallMiss(Code::Flags flags);
430 
431 #ifdef ENABLE_DEBUGGER_SUPPORT
432  Handle<Code> CompileCallDebugBreak(Code::Flags flags);
433  Handle<Code> CompileCallDebugPrepareStepIn(Code::Flags flags);
434 #endif
435 
436  // Static functions for generating parts of stubs.
437  static void GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,
438  int index,
439  Register prototype);
440 
441  // Generates prototype loading code that uses the objects from the
442  // context we were in when this function was called. If the context
443  // has changed, a jump to miss is performed. This ties the generated
444  // code to a particular context and so must not be used in cases
445  // where the generated code is not allowed to have references to
446  // objects from a context.
447  static void GenerateDirectLoadGlobalFunctionPrototype(MacroAssembler* masm,
448  int index,
449  Register prototype,
450  Label* miss);
451 
452  static void GenerateFastPropertyLoad(MacroAssembler* masm,
453  Register dst,
454  Register src,
455  Handle<JSObject> holder,
456  int index);
457 
458  static void GenerateLoadArrayLength(MacroAssembler* masm,
459  Register receiver,
460  Register scratch,
461  Label* miss_label);
462 
463  static void GenerateLoadStringLength(MacroAssembler* masm,
464  Register receiver,
465  Register scratch1,
466  Register scratch2,
467  Label* miss_label,
468  bool support_wrappers);
469 
470  static void GenerateLoadFunctionPrototype(MacroAssembler* masm,
471  Register receiver,
472  Register scratch1,
473  Register scratch2,
474  Label* miss_label);
475 
476  void GenerateStoreField(MacroAssembler* masm,
477  Handle<JSObject> object,
478  int index,
479  Handle<Map> transition,
480  Handle<String> name,
481  Register receiver_reg,
482  Register name_reg,
483  Register scratch1,
484  Register scratch2,
485  Label* miss_label);
486 
487  static void GenerateLoadMiss(MacroAssembler* masm,
488  Code::Kind kind);
489 
490  static void GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm);
491 
492  // Generates code that verifies that the property holder has not changed
493  // (checking maps of objects in the prototype chain for fast and global
494  // objects or doing negative lookup for slow objects, ensures that the
495  // property cells for global objects are still empty) and checks that the map
496  // of the holder has not changed. If necessary the function also generates
497  // code for security check in case of global object holders. Helps to make
498  // sure that the current IC is still valid.
499  //
500  // The scratch and holder registers are always clobbered, but the object
501  // register is only clobbered if it the same as the holder register. The
502  // function returns a register containing the holder - either object_reg or
503  // holder_reg.
504  // The function can optionally (when save_at_depth !=
505  // kInvalidProtoDepth) save the object at the given depth by moving
506  // it to [esp + kPointerSize].
508  Register object_reg,
509  Handle<JSObject> holder,
510  Register holder_reg,
511  Register scratch1,
512  Register scratch2,
513  Handle<String> name,
514  Label* miss) {
515  return CheckPrototypes(object, object_reg, holder, holder_reg, scratch1,
516  scratch2, name, kInvalidProtoDepth, miss);
517  }
518 
519  Register CheckPrototypes(Handle<JSObject> object,
520  Register object_reg,
521  Handle<JSObject> holder,
522  Register holder_reg,
523  Register scratch1,
524  Register scratch2,
525  Handle<String> name,
526  int save_at_depth,
527  Label* miss);
528 
529 
530  protected:
531  Handle<Code> GetCodeWithFlags(Code::Flags flags, const char* name);
532  Handle<Code> GetCodeWithFlags(Code::Flags flags, Handle<String> name);
533 
534  MacroAssembler* masm() { return &masm_; }
535  void set_failure(Failure* failure) { failure_ = failure; }
536 
537  void GenerateLoadField(Handle<JSObject> object,
538  Handle<JSObject> holder,
539  Register receiver,
540  Register scratch1,
541  Register scratch2,
542  Register scratch3,
543  int index,
544  Handle<String> name,
545  Label* miss);
546 
547  void GenerateLoadCallback(Handle<JSObject> object,
548  Handle<JSObject> holder,
549  Register receiver,
550  Register name_reg,
551  Register scratch1,
552  Register scratch2,
553  Register scratch3,
554  Register scratch4,
555  Handle<AccessorInfo> callback,
556  Handle<String> name,
557  Label* miss);
558 
559  void GenerateDictionaryLoadCallback(Register receiver,
560  Register name_reg,
561  Register scratch1,
562  Register scratch2,
563  Register scratch3,
564  Handle<AccessorInfo> callback,
565  Handle<String> name,
566  Label* miss);
567 
568  void GenerateLoadConstant(Handle<JSObject> object,
569  Handle<JSObject> holder,
570  Register receiver,
571  Register scratch1,
572  Register scratch2,
573  Register scratch3,
574  Handle<JSFunction> value,
575  Handle<String> name,
576  Label* miss);
577 
578  void GenerateLoadInterceptor(Handle<JSObject> object,
579  Handle<JSObject> holder,
580  LookupResult* lookup,
581  Register receiver,
582  Register name_reg,
583  Register scratch1,
584  Register scratch2,
585  Register scratch3,
586  Handle<String> name,
587  Label* miss);
588 
589  static void LookupPostInterceptor(Handle<JSObject> holder,
590  Handle<String> name,
591  LookupResult* lookup);
592 
593  Isolate* isolate() { return isolate_; }
594  Heap* heap() { return isolate()->heap(); }
595  Factory* factory() { return isolate()->factory(); }
596 
597  private:
598  Isolate* isolate_;
599  MacroAssembler masm_;
600  Failure* failure_;
601 };
602 
603 
604 class LoadStubCompiler: public StubCompiler {
605  public:
606  explicit LoadStubCompiler(Isolate* isolate) : StubCompiler(isolate) { }
607 
609  Handle<JSObject> object,
610  Handle<JSObject> last);
611 
613  Handle<JSObject> holder,
614  int index,
615  Handle<String> name);
616 
618  Handle<JSObject> object,
619  Handle<JSObject> holder,
620  Handle<AccessorInfo> callback);
621 
622  static void GenerateLoadViaGetter(MacroAssembler* masm,
623  Handle<JSFunction> getter);
624 
626  Handle<JSObject> receiver,
627  Handle<JSObject> holder,
628  Handle<JSFunction> getter);
629 
631  Handle<JSObject> holder,
632  Handle<JSFunction> value,
633  Handle<String> name);
634 
636  Handle<JSObject> holder,
637  Handle<String> name);
638 
640  Handle<GlobalObject> holder,
642  Handle<String> name,
643  bool is_dont_delete);
644 
645  private:
646  Handle<Code> GetCode(Code::StubType type, Handle<String> name);
647 };
648 
649 
650 class KeyedLoadStubCompiler: public StubCompiler {
651  public:
652  explicit KeyedLoadStubCompiler(Isolate* isolate) : StubCompiler(isolate) { }
653 
655  Handle<JSObject> object,
656  Handle<JSObject> holder,
657  int index);
658 
660  Handle<JSObject> object,
661  Handle<JSObject> holder,
662  Handle<AccessorInfo> callback);
663 
665  Handle<JSObject> object,
666  Handle<JSObject> holder,
667  Handle<JSFunction> value);
668 
670  Handle<JSObject> holder,
671  Handle<String> name);
672 
674 
676 
678 
680 
682  CodeHandleList* handler_ics);
683 
684  static void GenerateLoadExternalArray(MacroAssembler* masm,
685  ElementsKind elements_kind);
686 
687  static void GenerateLoadFastElement(MacroAssembler* masm);
688 
690 
692 
693  private:
694  Handle<Code> GetCode(Code::StubType type,
695  Handle<String> name,
696  InlineCacheState state = MONOMORPHIC);
697 };
698 
699 
700 class StoreStubCompiler: public StubCompiler {
701  public:
702  StoreStubCompiler(Isolate* isolate, StrictModeFlag strict_mode)
703  : StubCompiler(isolate), strict_mode_(strict_mode) { }
704 
705 
707  int index,
708  Handle<Map> transition,
709  Handle<String> name);
710 
712  Handle<JSObject> receiver,
713  Handle<JSObject> holder,
714  Handle<AccessorInfo> callback);
715 
716  static void GenerateStoreViaSetter(MacroAssembler* masm,
717  Handle<JSFunction> setter);
718 
720  Handle<JSObject> receiver,
721  Handle<JSObject> holder,
722  Handle<JSFunction> setter);
723 
725  Handle<String> name);
726 
729  Handle<String> name);
730 
731  private:
732  Handle<Code> GetCode(Code::StubType type, Handle<String> name);
733 
734  StrictModeFlag strict_mode_;
735 };
736 
737 
738 class KeyedStoreStubCompiler: public StubCompiler {
739  public:
741  StrictModeFlag strict_mode,
742  KeyedAccessGrowMode grow_mode)
743  : StubCompiler(isolate),
744  strict_mode_(strict_mode),
745  grow_mode_(grow_mode) { }
746 
748  int index,
749  Handle<Map> transition,
750  Handle<String> name);
751 
753 
755  CodeHandleList* handler_stubs,
756  MapHandleList* transitioned_maps);
757 
758  static void GenerateStoreFastElement(MacroAssembler* masm,
759  bool is_js_array,
760  ElementsKind element_kind,
761  KeyedAccessGrowMode grow_mode);
762 
764  bool is_js_array,
765  KeyedAccessGrowMode grow_mode);
766 
767  static void GenerateStoreExternalArray(MacroAssembler* masm,
768  ElementsKind elements_kind);
769 
771 
772  private:
773  Handle<Code> GetCode(Code::StubType type,
774  Handle<String> name,
775  InlineCacheState state = MONOMORPHIC);
776 
777  StrictModeFlag strict_mode_;
778  KeyedAccessGrowMode grow_mode_;
779 };
780 
781 
782 // Subset of FUNCTIONS_WITH_ID_LIST with custom constant/global call
783 // IC stubs.
784 #define CUSTOM_CALL_IC_GENERATORS(V) \
785  V(ArrayPush) \
786  V(ArrayPop) \
787  V(StringCharCodeAt) \
788  V(StringCharAt) \
789  V(StringFromCharCode) \
790  V(MathFloor) \
791  V(MathAbs)
792 
793 
794 class CallOptimization;
795 
796 class CallStubCompiler: public StubCompiler {
797  public:
798  CallStubCompiler(Isolate* isolate,
799  int argc,
800  Code::Kind kind,
801  Code::ExtraICState extra_state,
802  InlineCacheHolderFlag cache_holder);
803 
805  Handle<JSObject> holder,
806  int index,
807  Handle<String> name);
808 
810  Handle<JSObject> holder,
811  Handle<JSFunction> function,
812  Handle<String> name,
813  CheckType check);
814 
816  Handle<JSObject> holder,
817  Handle<String> name);
818 
820  Handle<GlobalObject> holder,
822  Handle<JSFunction> function,
823  Handle<String> name);
824 
825  static bool HasCustomCallGenerator(Handle<JSFunction> function);
826 
827  private:
828  // Compiles a custom call constant/global IC. For constant calls cell is
829  // NULL. Returns an empty handle if there is no custom call code for the
830  // given function.
831  Handle<Code> CompileCustomCall(Handle<Object> object,
832  Handle<JSObject> holder,
834  Handle<JSFunction> function,
835  Handle<String> name);
836 
837 #define DECLARE_CALL_GENERATOR(name) \
838  Handle<Code> Compile##name##Call(Handle<Object> object, \
839  Handle<JSObject> holder, \
840  Handle<JSGlobalPropertyCell> cell, \
841  Handle<JSFunction> function, \
842  Handle<String> fname);
844 #undef DECLARE_CALL_GENERATOR
845 
846  Handle<Code> CompileFastApiCall(const CallOptimization& optimization,
847  Handle<Object> object,
848  Handle<JSObject> holder,
849  Handle<JSGlobalPropertyCell> cell,
850  Handle<JSFunction> function,
851  Handle<String> name);
852 
853  Handle<Code> GetCode(Code::StubType type, Handle<String> name);
854  Handle<Code> GetCode(Handle<JSFunction> function);
855 
856  const ParameterCount& arguments() { return arguments_; }
857 
858  void GenerateNameCheck(Handle<String> name, Label* miss);
859 
860  void GenerateGlobalReceiverCheck(Handle<JSObject> object,
861  Handle<JSObject> holder,
862  Handle<String> name,
863  Label* miss);
864 
865  // Generates code to load the function from the cell checking that
866  // it still contains the same function.
867  void GenerateLoadFunctionFromCell(Handle<JSGlobalPropertyCell> cell,
868  Handle<JSFunction> function,
869  Label* miss);
870 
871  // Generates a jump to CallIC miss stub.
872  void GenerateMissBranch();
873 
874  const ParameterCount arguments_;
875  const Code::Kind kind_;
876  const Code::ExtraICState extra_state_;
877  const InlineCacheHolderFlag cache_holder_;
878 };
879 
880 
881 class ConstructStubCompiler: public StubCompiler {
882  public:
883  explicit ConstructStubCompiler(Isolate* isolate) : StubCompiler(isolate) { }
884 
886 
887  private:
888  Handle<Code> GetCode();
889 };
890 
891 
892 // Holds information about possible function call optimizations.
893 class CallOptimization BASE_EMBEDDED {
894  public:
895  explicit CallOptimization(LookupResult* lookup);
896 
897  explicit CallOptimization(Handle<JSFunction> function);
898 
899  bool is_constant_call() const {
900  return !constant_function_.is_null();
901  }
902 
904  ASSERT(is_constant_call());
905  return constant_function_;
906  }
907 
908  bool is_simple_api_call() const {
909  return is_simple_api_call_;
910  }
911 
913  ASSERT(is_simple_api_call());
914  return expected_receiver_type_;
915  }
916 
918  ASSERT(is_simple_api_call());
919  return api_call_info_;
920  }
921 
922  // Returns the depth of the object having the expected type in the
923  // prototype chain between the two arguments.
924  int GetPrototypeDepthOfExpectedType(Handle<JSObject> object,
925  Handle<JSObject> holder) const;
926 
927  private:
928  void Initialize(Handle<JSFunction> function);
929 
930  // Determines whether the given function can be called using the
931  // fast api call builtin.
932  void AnalyzePossibleApiFunction(Handle<JSFunction> function);
933 
934  Handle<JSFunction> constant_function_;
935  bool is_simple_api_call_;
936  Handle<FunctionTemplateInfo> expected_receiver_type_;
937  Handle<CallHandlerInfo> api_call_info_;
938 };
939 
940 
941 } } // namespace v8::internal
942 
943 #endif // V8_STUB_CACHE_H_
byte * Address
Definition: globals.h:157
Handle< Code > CompileLoadFunctionPrototype(Handle< String > name)
Handle< Code > CompileLoadCallback(Handle< String > name, Handle< JSObject > object, Handle< JSObject > holder, Handle< AccessorInfo > callback)
static void GenerateStoreViaSetter(MacroAssembler *masm, Handle< JSFunction > setter)
Handle< Code > CompileStoreField(Handle< JSObject > object, int index, Handle< Map > transition, Handle< String > name)
Handle< Code > ComputeLoadNormal()
Definition: stub-cache.cc:235
bool is_simple_api_call() const
Definition: stub-cache.h:908
Handle< Code > ComputeCallGlobal(int argc, Code::Kind, Code::ExtraICState extra_state, Handle< String > name, Handle< JSObject > receiver, Handle< GlobalObject > holder, Handle< JSGlobalPropertyCell > cell, Handle< JSFunction > function)
Definition: stub-cache.cc:704
Handle< Code > CompileLoadNonexistent(Handle< String > name, Handle< JSObject > object, Handle< JSObject > last)
Handle< Code > ComputeKeyedLoadFunctionPrototype(Handle< String > name, Handle< JSFunction > receiver)
Definition: stub-cache.cc:373
Handle< Code > ComputeStoreField(Handle< String > name, Handle< JSObject > receiver, int field_index, Handle< Map > transition, StrictModeFlag strict_mode)
Definition: stub-cache.cc:390
Handle< Code > CompileStoreElement(Handle< Map > receiver_map)
void GenerateProbe(MacroAssembler *masm, Code::Flags flags, Register receiver, Register name, Register scratch, Register extra, Register extra2=no_reg, Register extra3=no_reg)
Code * Set(String *name, Map *map, Code *code)
Definition: stub-cache.cc:59
static void GenerateStoreExternalArray(MacroAssembler *masm, ElementsKind elements_kind)
Handle< Code > ComputeCallMiss(int argc, Code::Kind kind, Code::ExtraICState state)
Definition: stub-cache.cc:865
void set_failure(Failure *failure)
Definition: stub-cache.h:535
static void GenerateLoadFastDoubleElement(MacroAssembler *masm)
bool is_constant_call() const
Definition: stub-cache.h:899
String * key
Definition: stub-cache.h:70
Handle< Code > ComputeLoadCallback(Handle< String > name, Handle< JSObject > receiver, Handle< JSObject > holder, Handle< AccessorInfo > callback)
Definition: stub-cache.cc:155
SCTableReference map_reference(StubCache::Table table)
Definition: stub-cache.h:292
Handle< Code > ComputeKeyedLoadOrStoreElement(Handle< Map > receiver_map, KeyedIC::StubKind stub_kind, StrictModeFlag strict_mode)
Definition: stub-cache.cc:412
#define ASSERT(condition)
Definition: checks.h:270
Handle< Code > ComputeStoreViaSetter(Handle< String > name, Handle< JSObject > receiver, Handle< JSObject > holder, Handle< JSFunction > setter, StrictModeFlag strict_mode)
Definition: stub-cache.cc:526
#define CUSTOM_CALL_IC_GENERATORS(V)
Definition: stub-cache.h:784
Handle< Code > ComputeCallMegamorphic(int argc, Code::Kind kind, Code::ExtraICState state)
Definition: stub-cache.cc:846
Handle< Code > ComputeKeyedLoadInterceptor(Handle< String > name, Handle< JSObject > receiver, Handle< JSObject > holder)
Definition: stub-cache.cc:301
Handle< Code > ComputeKeyedLoadCallback(Handle< String > name, Handle< JSObject > receiver, Handle< JSObject > holder, Handle< AccessorInfo > callback)
Definition: stub-cache.cc:319
#define DECLARE_CALL_GENERATOR(name)
Definition: stub-cache.h:837
Factory * factory()
Definition: isolate.h:992
void CollectMatchingMaps(SmallMapList *types, String *name, Code::Flags flags, Handle< Context > native_context, Zone *zone)
Definition: stub-cache.cc:938
StubCompiler(Isolate *isolate)
Definition: stub-cache.h:419
CallStubCompiler(Isolate *isolate, int argc, Code::Kind kind, Code::ExtraICState extra_state, InlineCacheHolderFlag cache_holder)
Definition: stub-cache.cc:1431
Handle< Code > CompileLoadField(Handle< JSObject > object, Handle< JSObject > holder, int index, Handle< String > name)
Handle< Code > CompileStoreInterceptor(Handle< JSObject > object, Handle< String > name)
KeyedLoadStubCompiler(Isolate *isolate)
Definition: stub-cache.h:652
unsigned int seed
Definition: test-strings.cc:18
Handle< Code > CompileStoreField(Handle< JSObject > object, int index, Handle< Map > transition, Handle< String > name)
friend class SCTableReference
Definition: stub-cache.h:393
Handle< Code > ComputeKeyedLoadArrayLength(Handle< String > name, Handle< JSArray > receiver)
Definition: stub-cache.cc:340
Handle< Code > ComputeCallInterceptor(int argc, Code::Kind, Code::ExtraICState extra_state, Handle< String > name, Handle< Object > object, Handle< JSObject > holder)
Definition: stub-cache.cc:667
Handle< Code > ComputeCallArguments(int argc, Code::Kind kind)
Definition: stub-cache.cc:829
Handle< Code > ComputeLoadField(Handle< String > name, Handle< JSObject > receiver, Handle< JSObject > holder, int field_index)
Definition: stub-cache.cc:136
Handle< Code > CompileLoadInterceptor(Handle< JSObject > object, Handle< JSObject > holder, Handle< String > name)
Code * value
Definition: stub-cache.h:71
MacroAssembler * masm()
Definition: stub-cache.h:534
#define UNREACHABLE()
Definition: checks.h:50
Handle< Code > ComputeStoreNormal(StrictModeFlag strict_mode)
Definition: stub-cache.cc:480
STATIC_ASSERT((FixedDoubleArray::kHeaderSize &kDoubleAlignmentMask)==0)
Handle< Code > ComputeCallField(int argc, Code::Kind, Code::ExtraICState extra_state, Handle< String > name, Handle< Object > object, Handle< JSObject > holder, int index)
Definition: stub-cache.cc:629
Handle< Code > CompileCallGlobal(Handle< JSObject > object, Handle< GlobalObject > holder, Handle< JSGlobalPropertyCell > cell, Handle< JSFunction > function, Handle< String > name)
Handle< Code > CompileLoadField(Handle< String > name, Handle< JSObject > object, Handle< JSObject > holder, int index)
static void GenerateLoadViaGetter(MacroAssembler *masm, Handle< JSFunction > getter)
Handle< Code > CompileStoreGlobal(Handle< GlobalObject > object, Handle< JSGlobalPropertyCell > holder, Handle< String > name)
Handle< Code > CompileLoadViaGetter(Handle< String > name, Handle< JSObject > receiver, Handle< JSObject > holder, Handle< JSFunction > getter)
Handle< Code > CompileLoadConstant(Handle< JSObject > object, Handle< JSObject > holder, Handle< JSFunction > value, Handle< String > name)
Definition: stub-cache.h:69
Handle< Code > CompileLoadConstant(Handle< String > name, Handle< JSObject > object, Handle< JSObject > holder, Handle< JSFunction > value)
StubCache::Entry * first_entry(StubCache::Table table)
Definition: stub-cache.h:304
Handle< Code > CompileCallField(Handle< JSObject > object, Handle< JSObject > holder, int index, Handle< String > name)
Map * map
Definition: stub-cache.h:72
static void GenerateStoreFastElement(MacroAssembler *masm, bool is_js_array, ElementsKind element_kind, KeyedAccessGrowMode grow_mode)
Handle< Code > CompileLoadStringLength(Handle< String > name)
Handle< Code > ComputeKeyedLoadStringLength(Handle< String > name, Handle< String > receiver)
Definition: stub-cache.cc:356
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: globals.h:307
Handle< Code > CompileLoadGlobal(Handle< JSObject > object, Handle< GlobalObject > holder, Handle< JSGlobalPropertyCell > cell, Handle< String > name, bool is_dont_delete)
Handle< Code > CompileStoreCallback(Handle< String > name, Handle< JSObject > receiver, Handle< JSObject > holder, Handle< AccessorInfo > callback)
Handle< Code > ComputeStoreGlobal(Handle< String > name, Handle< GlobalObject > receiver, Handle< JSGlobalPropertyCell > cell, StrictModeFlag strict_mode)
Definition: stub-cache.cc:487
#define BASE_EMBEDDED
Definition: allocation.h:68
Handle< Code > ComputeStoreInterceptor(Handle< String > name, Handle< JSObject > receiver, StrictModeFlag strict_mode)
Definition: stub-cache.cc:546
static void GenerateLoadDictionaryElement(MacroAssembler *masm)
static void GenerateLoadExternalArray(MacroAssembler *masm, ElementsKind elements_kind)
Handle< Code > ComputeLoadViaGetter(Handle< String > name, Handle< JSObject > receiver, Handle< JSObject > holder, Handle< JSFunction > getter)
Definition: stub-cache.cc:176
Handle< FunctionTemplateInfo > expected_receiver_type() const
Definition: stub-cache.h:912
SCTableReference key_reference(StubCache::Table table)
Definition: stub-cache.h:286
Register CheckPrototypes(Handle< JSObject > object, Register object_reg, Handle< JSObject > holder, Register holder_reg, Register scratch1, Register scratch2, Handle< String > name, Label *miss)
Definition: stub-cache.h:507
Handle< CallHandlerInfo > api_call_info() const
Definition: stub-cache.h:917
Handle< Code > ComputeKeyedLoadField(Handle< String > name, Handle< JSObject > receiver, Handle< JSObject > holder, int field_index)
Definition: stub-cache.cc:261
Handle< Code > ComputeCallNormal(int argc, Code::Kind kind, Code::ExtraICState state)
Definition: stub-cache.cc:812
Handle< Code > ComputeKeyedStoreField(Handle< String > name, Handle< JSObject > receiver, int field_index, Handle< Map > transition, StrictModeFlag strict_mode)
Definition: stub-cache.cc:562
Handle< Code > CompileCallInterceptor(Handle< JSObject > object, Handle< JSObject > holder, Handle< String > name)
static void GenerateLoadFastElement(MacroAssembler *masm)
ConstructStubCompiler(Isolate *isolate)
Definition: stub-cache.h:883
friend class Isolate
Definition: stub-cache.h:392
static void GenerateStoreFastDoubleElement(MacroAssembler *masm, bool is_js_array, KeyedAccessGrowMode grow_mode)
LoadStubCompiler(Isolate *isolate)
Definition: stub-cache.h:606
Handle< Code > ComputeKeyedCallInitialize(int argc)
Definition: stub-cache.cc:788
Handle< Code > CompileLoadArrayLength(Handle< String > name)
Handle< Code > CompileCallConstant(Handle< Object > object, Handle< JSObject > holder, Handle< JSFunction > function, Handle< String > name, CheckType check)
const int kHeapObjectTagSize
Definition: v8.h:4010
SCTableReference value_reference(StubCache::Table table)
Definition: stub-cache.h:298
static bool HasCustomCallGenerator(Handle< JSFunction > function)
Definition: stub-cache.cc:1444
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
Handle< Code > ComputeCallInitialize(int argc, RelocInfo::Mode mode)
Definition: stub-cache.cc:783
DECLARE_RUNTIME_FUNCTION(MaybeObject *, LoadCallbackProperty)
Code * FindCallInitialize(int argc, RelocInfo::Mode mode, Code::Kind kind)
Definition: stub-cache.cc:742
static const int kFlagsNotUsedInLookup
Definition: objects.h:4649
Handle< Code > ComputeCallPreMonomorphic(int argc, Code::Kind kind, Code::ExtraICState extra_state)
Definition: stub-cache.cc:794
const int kInvalidProtoDepth
const Register no_reg
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
Handle< Code > ComputeLoadNonexistent(Handle< String > name, Handle< JSObject > receiver)
Definition: stub-cache.cc:103
Handle< Code > ComputeLoadConstant(Handle< String > name, Handle< JSObject > receiver, Handle< JSObject > holder, Handle< JSFunction > value)
Definition: stub-cache.cc:196
Handle< Code > CompileLoadCallback(Handle< String > name, Handle< JSObject > object, Handle< JSObject > holder, Handle< AccessorInfo > callback)
Handle< Code > ComputeLoadInterceptor(Handle< String > name, Handle< JSObject > receiver, Handle< JSObject > holder)
Definition: stub-cache.cc:216
static const int kHashShift
Definition: objects.h:7341
Handle< Code > CompileLoadPolymorphic(MapHandleList *receiver_maps, CodeHandleList *handler_ics)
Handle< Code > ComputeCallConstant(int argc, Code::Kind, Code::ExtraICState extra_state, Handle< String > name, Handle< Object > object, Handle< JSObject > holder, Handle< JSFunction > function)
Definition: stub-cache.cc:588
Handle< Code > CompileLoadInterceptor(Handle< JSObject > object, Handle< JSObject > holder, Handle< String > name)
Handle< Code > CompileStorePolymorphic(MapHandleList *receiver_maps, CodeHandleList *handler_stubs, MapHandleList *transitioned_maps)
KeyedAccessGrowMode
Definition: objects.h:142
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
KeyedStoreStubCompiler(Isolate *isolate, StrictModeFlag strict_mode, KeyedAccessGrowMode grow_mode)
Definition: stub-cache.h:740
Handle< JSFunction > constant_function() const
Definition: stub-cache.h:903
void check(i::Vector< const char > string)
Handle< Code > ComputeKeyedLoadConstant(Handle< String > name, Handle< JSObject > receiver, Handle< JSObject > holder, Handle< JSFunction > value)
Definition: stub-cache.cc:281
Handle< Code > CompileLoadElement(Handle< Map > receiver_map)
Handle< Code > CompileConstructStub(Handle< JSFunction > function)
Handle< Code > CompileStoreViaSetter(Handle< String > name, Handle< JSObject > receiver, Handle< JSObject > holder, Handle< JSFunction > setter)
Handle< Code > ComputeLoadGlobal(Handle< String > name, Handle< JSObject > receiver, Handle< GlobalObject > holder, Handle< JSGlobalPropertyCell > cell, bool is_dont_delete)
Definition: stub-cache.cc:240
Address address() const
Definition: stub-cache.h:56
StoreStubCompiler(Isolate *isolate, StrictModeFlag strict_mode)
Definition: stub-cache.h:702
Handle< Code > ComputeStoreCallback(Handle< String > name, Handle< JSObject > receiver, Handle< JSObject > holder, Handle< AccessorInfo > callback, StrictModeFlag strict_mode)
Definition: stub-cache.cc:505
static void GenerateStoreDictionaryElement(MacroAssembler *masm)
Definition: stub-cache.cc:1425