Home | History | Annotate | Download | only in src
      1 // Copyright 2011 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_BUILTINS_H_
      6 #define V8_BUILTINS_H_
      7 
      8 namespace v8 {
      9 namespace internal {
     10 
     11 // Specifies extra arguments required by a C++ builtin.
     12 enum BuiltinExtraArguments {
     13   NO_EXTRA_ARGUMENTS = 0,
     14   NEEDS_CALLED_FUNCTION = 1
     15 };
     16 
     17 
     18 #define CODE_AGE_LIST_WITH_ARG(V, A)     \
     19   V(Quadragenarian, A)                   \
     20   V(Quinquagenarian, A)                  \
     21   V(Sexagenarian, A)                     \
     22   V(Septuagenarian, A)                   \
     23   V(Octogenarian, A)
     24 
     25 #define CODE_AGE_LIST_IGNORE_ARG(X, V) V(X)
     26 
     27 #define CODE_AGE_LIST(V) \
     28   CODE_AGE_LIST_WITH_ARG(CODE_AGE_LIST_IGNORE_ARG, V)
     29 
     30 #define CODE_AGE_LIST_COMPLETE(V)                  \
     31   V(NotExecuted)                                   \
     32   V(ExecutedOnce)                                  \
     33   V(NoAge)                                         \
     34   CODE_AGE_LIST_WITH_ARG(CODE_AGE_LIST_IGNORE_ARG, V)
     35 
     36 #define DECLARE_CODE_AGE_BUILTIN(C, V)             \
     37   V(Make##C##CodeYoungAgainOddMarking, BUILTIN,    \
     38     UNINITIALIZED, kNoExtraICState)                \
     39   V(Make##C##CodeYoungAgainEvenMarking, BUILTIN,   \
     40     UNINITIALIZED, kNoExtraICState)
     41 
     42 
     43 // Define list of builtins implemented in C++.
     44 #define BUILTIN_LIST_C(V)                                           \
     45   V(Illegal, NO_EXTRA_ARGUMENTS)                                    \
     46                                                                     \
     47   V(EmptyFunction, NO_EXTRA_ARGUMENTS)                              \
     48                                                                     \
     49   V(ArrayPush, NO_EXTRA_ARGUMENTS)                                  \
     50   V(ArrayPop, NO_EXTRA_ARGUMENTS)                                   \
     51   V(ArrayShift, NO_EXTRA_ARGUMENTS)                                 \
     52   V(ArrayUnshift, NO_EXTRA_ARGUMENTS)                               \
     53   V(ArraySlice, NO_EXTRA_ARGUMENTS)                                 \
     54   V(ArraySplice, NO_EXTRA_ARGUMENTS)                                \
     55   V(ArrayConcat, NO_EXTRA_ARGUMENTS)                                \
     56                                                                     \
     57   V(HandleApiCall, NEEDS_CALLED_FUNCTION)                           \
     58   V(HandleApiCallConstruct, NEEDS_CALLED_FUNCTION)                  \
     59   V(HandleApiCallAsFunction, NO_EXTRA_ARGUMENTS)                    \
     60   V(HandleApiCallAsConstructor, NO_EXTRA_ARGUMENTS)                 \
     61                                                                     \
     62   V(StrictModePoisonPill, NO_EXTRA_ARGUMENTS)                       \
     63   V(GeneratorPoisonPill, NO_EXTRA_ARGUMENTS)
     64 
     65 // Define list of builtins implemented in assembly.
     66 #define BUILTIN_LIST_A(V)                                               \
     67   V(ArgumentsAdaptorTrampoline,     BUILTIN, UNINITIALIZED,             \
     68                                     kNoExtraICState)                    \
     69   V(InOptimizationQueue,            BUILTIN, UNINITIALIZED,             \
     70                                     kNoExtraICState)                    \
     71   V(JSConstructStubGeneric,         BUILTIN, UNINITIALIZED,             \
     72                                     kNoExtraICState)                    \
     73   V(JSConstructStubApi,             BUILTIN, UNINITIALIZED,             \
     74                                     kNoExtraICState)                    \
     75   V(JSEntryTrampoline,              BUILTIN, UNINITIALIZED,             \
     76                                     kNoExtraICState)                    \
     77   V(JSConstructEntryTrampoline,     BUILTIN, UNINITIALIZED,             \
     78                                     kNoExtraICState)                    \
     79   V(CompileUnoptimized,             BUILTIN, UNINITIALIZED,             \
     80                                     kNoExtraICState)                    \
     81   V(CompileOptimized,               BUILTIN, UNINITIALIZED,             \
     82                                     kNoExtraICState)                    \
     83   V(CompileOptimizedConcurrent,     BUILTIN, UNINITIALIZED,             \
     84                                     kNoExtraICState)                    \
     85   V(NotifyDeoptimized,              BUILTIN, UNINITIALIZED,             \
     86                                     kNoExtraICState)                    \
     87   V(NotifySoftDeoptimized,          BUILTIN, UNINITIALIZED,             \
     88                                     kNoExtraICState)                    \
     89   V(NotifyLazyDeoptimized,          BUILTIN, UNINITIALIZED,             \
     90                                     kNoExtraICState)                    \
     91   V(NotifyStubFailure,              BUILTIN, UNINITIALIZED,             \
     92                                     kNoExtraICState)                    \
     93   V(NotifyStubFailureSaveDoubles,   BUILTIN, UNINITIALIZED,             \
     94                                     kNoExtraICState)                    \
     95                                                                         \
     96   V(LoadIC_Miss,                    BUILTIN, UNINITIALIZED,             \
     97                                     kNoExtraICState)                    \
     98   V(KeyedLoadIC_Miss,               BUILTIN, UNINITIALIZED,             \
     99                                     kNoExtraICState)                    \
    100   V(StoreIC_Miss,                   BUILTIN, UNINITIALIZED,             \
    101                                     kNoExtraICState)                    \
    102   V(KeyedStoreIC_Miss,              BUILTIN, UNINITIALIZED,             \
    103                                     kNoExtraICState)                    \
    104   V(LoadIC_Getter_ForDeopt,         LOAD_IC, MONOMORPHIC,               \
    105                                     kNoExtraICState)                    \
    106   V(KeyedLoadIC_Initialize,         KEYED_LOAD_IC, UNINITIALIZED,       \
    107                                     kNoExtraICState)                    \
    108   V(KeyedLoadIC_PreMonomorphic,     KEYED_LOAD_IC, PREMONOMORPHIC,      \
    109                                     kNoExtraICState)                    \
    110   V(KeyedLoadIC_Generic,            KEYED_LOAD_IC, GENERIC,             \
    111                                     kNoExtraICState)                    \
    112   V(KeyedLoadIC_String,             KEYED_LOAD_IC, MEGAMORPHIC,         \
    113                                     kNoExtraICState)                    \
    114   V(KeyedLoadIC_IndexedInterceptor, KEYED_LOAD_IC, MONOMORPHIC,         \
    115                                     kNoExtraICState)                    \
    116   V(KeyedLoadIC_SloppyArguments,    KEYED_LOAD_IC, MONOMORPHIC,         \
    117                                     kNoExtraICState)                    \
    118                                                                         \
    119   V(StoreIC_Setter_ForDeopt,        STORE_IC, MONOMORPHIC,              \
    120                                     StoreIC::kStrictModeState)          \
    121                                                                         \
    122   V(KeyedStoreIC_Initialize,        KEYED_STORE_IC, UNINITIALIZED,      \
    123                                     kNoExtraICState)                    \
    124   V(KeyedStoreIC_PreMonomorphic,    KEYED_STORE_IC, PREMONOMORPHIC,     \
    125                                     kNoExtraICState)                    \
    126   V(KeyedStoreIC_Generic,           KEYED_STORE_IC, GENERIC,            \
    127                                     kNoExtraICState)                    \
    128                                                                         \
    129   V(KeyedStoreIC_Initialize_Strict, KEYED_STORE_IC, UNINITIALIZED,      \
    130                                     StoreIC::kStrictModeState)          \
    131   V(KeyedStoreIC_PreMonomorphic_Strict, KEYED_STORE_IC, PREMONOMORPHIC, \
    132                                     StoreIC::kStrictModeState)          \
    133   V(KeyedStoreIC_Generic_Strict,    KEYED_STORE_IC, GENERIC,            \
    134                                     StoreIC::kStrictModeState)          \
    135   V(KeyedStoreIC_SloppyArguments,   KEYED_STORE_IC, MONOMORPHIC,        \
    136                                     kNoExtraICState)                    \
    137                                                                         \
    138   /* Uses KeyedLoadIC_Initialize; must be after in list. */             \
    139   V(FunctionCall,                   BUILTIN, UNINITIALIZED,             \
    140                                     kNoExtraICState)                    \
    141   V(FunctionApply,                  BUILTIN, UNINITIALIZED,             \
    142                                     kNoExtraICState)                    \
    143                                                                         \
    144   V(InternalArrayCode,              BUILTIN, UNINITIALIZED,             \
    145                                     kNoExtraICState)                    \
    146   V(ArrayCode,                      BUILTIN, UNINITIALIZED,             \
    147                                     kNoExtraICState)                    \
    148                                                                         \
    149   V(StringConstructCode,            BUILTIN, UNINITIALIZED,             \
    150                                     kNoExtraICState)                    \
    151                                                                         \
    152   V(OnStackReplacement,             BUILTIN, UNINITIALIZED,             \
    153                                     kNoExtraICState)                    \
    154   V(InterruptCheck,                 BUILTIN, UNINITIALIZED,             \
    155                                     kNoExtraICState)                    \
    156   V(OsrAfterStackCheck,             BUILTIN, UNINITIALIZED,             \
    157                                     kNoExtraICState)                    \
    158   V(StackCheck,                     BUILTIN, UNINITIALIZED,             \
    159                                     kNoExtraICState)                    \
    160                                                                         \
    161   V(MarkCodeAsExecutedOnce,         BUILTIN, UNINITIALIZED,             \
    162                                     kNoExtraICState)                    \
    163   V(MarkCodeAsExecutedTwice,        BUILTIN, UNINITIALIZED,             \
    164                                     kNoExtraICState)                    \
    165   CODE_AGE_LIST_WITH_ARG(DECLARE_CODE_AGE_BUILTIN, V)
    166 
    167 // Define list of builtin handlers implemented in assembly.
    168 #define BUILTIN_LIST_H(V)                                               \
    169   V(LoadIC_Slow,                    LOAD_IC)                            \
    170   V(KeyedLoadIC_Slow,               KEYED_LOAD_IC)                      \
    171   V(StoreIC_Slow,                   STORE_IC)                           \
    172   V(KeyedStoreIC_Slow,              KEYED_STORE_IC)                     \
    173   V(LoadIC_Normal,                  LOAD_IC)                            \
    174   V(StoreIC_Normal,                 STORE_IC)
    175 
    176 // Define list of builtins used by the debugger implemented in assembly.
    177 #define BUILTIN_LIST_DEBUG_A(V)                                               \
    178   V(Return_DebugBreak,                         BUILTIN, DEBUG_STUB,           \
    179                                                DEBUG_BREAK)                   \
    180   V(CallFunctionStub_DebugBreak,               BUILTIN, DEBUG_STUB,           \
    181                                                DEBUG_BREAK)                   \
    182   V(CallConstructStub_DebugBreak,              BUILTIN, DEBUG_STUB,           \
    183                                                DEBUG_BREAK)                   \
    184   V(CallConstructStub_Recording_DebugBreak,    BUILTIN, DEBUG_STUB,           \
    185                                                DEBUG_BREAK)                   \
    186   V(CallICStub_DebugBreak,                     CALL_IC, DEBUG_STUB,           \
    187                                                DEBUG_BREAK)                   \
    188   V(LoadIC_DebugBreak,                         LOAD_IC, DEBUG_STUB,           \
    189                                                DEBUG_BREAK)                   \
    190   V(KeyedLoadIC_DebugBreak,                    KEYED_LOAD_IC, DEBUG_STUB,     \
    191                                                DEBUG_BREAK)                   \
    192   V(StoreIC_DebugBreak,                        STORE_IC, DEBUG_STUB,          \
    193                                                DEBUG_BREAK)                   \
    194   V(KeyedStoreIC_DebugBreak,                   KEYED_STORE_IC, DEBUG_STUB,    \
    195                                                DEBUG_BREAK)                   \
    196   V(CompareNilIC_DebugBreak,                   COMPARE_NIL_IC, DEBUG_STUB,    \
    197                                                DEBUG_BREAK)                   \
    198   V(Slot_DebugBreak,                           BUILTIN, DEBUG_STUB,           \
    199                                                DEBUG_BREAK)                   \
    200   V(PlainReturn_LiveEdit,                      BUILTIN, DEBUG_STUB,           \
    201                                                DEBUG_BREAK)                   \
    202   V(FrameDropper_LiveEdit,                     BUILTIN, DEBUG_STUB,           \
    203                                                DEBUG_BREAK)
    204 
    205 // Define list of builtins implemented in JavaScript.
    206 #define BUILTINS_LIST_JS(V)              \
    207   V(EQUALS, 1)                           \
    208   V(STRICT_EQUALS, 1)                    \
    209   V(COMPARE, 2)                          \
    210   V(ADD, 1)                              \
    211   V(SUB, 1)                              \
    212   V(MUL, 1)                              \
    213   V(DIV, 1)                              \
    214   V(MOD, 1)                              \
    215   V(BIT_OR, 1)                           \
    216   V(BIT_AND, 1)                          \
    217   V(BIT_XOR, 1)                          \
    218   V(SHL, 1)                              \
    219   V(SAR, 1)                              \
    220   V(SHR, 1)                              \
    221   V(DELETE, 2)                           \
    222   V(IN, 1)                               \
    223   V(INSTANCE_OF, 1)                      \
    224   V(FILTER_KEY, 1)                       \
    225   V(CALL_NON_FUNCTION, 0)                \
    226   V(CALL_NON_FUNCTION_AS_CONSTRUCTOR, 0) \
    227   V(CALL_FUNCTION_PROXY, 1)                \
    228   V(CALL_FUNCTION_PROXY_AS_CONSTRUCTOR, 1) \
    229   V(TO_OBJECT, 0)                        \
    230   V(TO_NUMBER, 0)                        \
    231   V(TO_STRING, 0)                        \
    232   V(STRING_ADD_LEFT, 1)                  \
    233   V(STRING_ADD_RIGHT, 1)                 \
    234   V(APPLY_PREPARE, 1)                    \
    235   V(STACK_OVERFLOW, 1)
    236 
    237 class BuiltinFunctionTable;
    238 class ObjectVisitor;
    239 
    240 
    241 class Builtins {
    242  public:
    243   ~Builtins();
    244 
    245   // Generate all builtin code objects. Should be called once during
    246   // isolate initialization.
    247   void SetUp(Isolate* isolate, bool create_heap_objects);
    248   void TearDown();
    249 
    250   // Garbage collection support.
    251   void IterateBuiltins(ObjectVisitor* v);
    252 
    253   // Disassembler support.
    254   const char* Lookup(byte* pc);
    255 
    256   enum Name {
    257 #define DEF_ENUM_C(name, ignore) k##name,
    258 #define DEF_ENUM_A(name, kind, state, extra) k##name,
    259 #define DEF_ENUM_H(name, kind) k##name,
    260     BUILTIN_LIST_C(DEF_ENUM_C)
    261     BUILTIN_LIST_A(DEF_ENUM_A)
    262     BUILTIN_LIST_H(DEF_ENUM_H)
    263     BUILTIN_LIST_DEBUG_A(DEF_ENUM_A)
    264 #undef DEF_ENUM_C
    265 #undef DEF_ENUM_A
    266     builtin_count
    267   };
    268 
    269   enum CFunctionId {
    270 #define DEF_ENUM_C(name, ignore) c_##name,
    271     BUILTIN_LIST_C(DEF_ENUM_C)
    272 #undef DEF_ENUM_C
    273     cfunction_count
    274   };
    275 
    276   enum JavaScript {
    277 #define DEF_ENUM(name, ignore) name,
    278     BUILTINS_LIST_JS(DEF_ENUM)
    279 #undef DEF_ENUM
    280     id_count
    281   };
    282 
    283 #define DECLARE_BUILTIN_ACCESSOR_C(name, ignore) Handle<Code> name();
    284 #define DECLARE_BUILTIN_ACCESSOR_A(name, kind, state, extra) \
    285   Handle<Code> name();
    286 #define DECLARE_BUILTIN_ACCESSOR_H(name, kind) Handle<Code> name();
    287   BUILTIN_LIST_C(DECLARE_BUILTIN_ACCESSOR_C)
    288   BUILTIN_LIST_A(DECLARE_BUILTIN_ACCESSOR_A)
    289   BUILTIN_LIST_H(DECLARE_BUILTIN_ACCESSOR_H)
    290   BUILTIN_LIST_DEBUG_A(DECLARE_BUILTIN_ACCESSOR_A)
    291 #undef DECLARE_BUILTIN_ACCESSOR_C
    292 #undef DECLARE_BUILTIN_ACCESSOR_A
    293 
    294   Code* builtin(Name name) {
    295     // Code::cast cannot be used here since we access builtins
    296     // during the marking phase of mark sweep. See IC::Clear.
    297     return reinterpret_cast<Code*>(builtins_[name]);
    298   }
    299 
    300   Address builtin_address(Name name) {
    301     return reinterpret_cast<Address>(&builtins_[name]);
    302   }
    303 
    304   static Address c_function_address(CFunctionId id) {
    305     return c_functions_[id];
    306   }
    307 
    308   static const char* GetName(JavaScript id) { return javascript_names_[id]; }
    309   const char* name(int index) {
    310     ASSERT(index >= 0);
    311     ASSERT(index < builtin_count);
    312     return names_[index];
    313   }
    314   static int GetArgumentsCount(JavaScript id) { return javascript_argc_[id]; }
    315   Handle<Code> GetCode(JavaScript id, bool* resolved);
    316   static int NumberOfJavaScriptBuiltins() { return id_count; }
    317 
    318   bool is_initialized() const { return initialized_; }
    319 
    320  private:
    321   Builtins();
    322 
    323   // The external C++ functions called from the code.
    324   static Address const c_functions_[cfunction_count];
    325 
    326   // Note: These are always Code objects, but to conform with
    327   // IterateBuiltins() above which assumes Object**'s for the callback
    328   // function f, we use an Object* array here.
    329   Object* builtins_[builtin_count];
    330   const char* names_[builtin_count];
    331   static const char* const javascript_names_[id_count];
    332   static int const javascript_argc_[id_count];
    333 
    334   static void Generate_Adaptor(MacroAssembler* masm,
    335                                CFunctionId id,
    336                                BuiltinExtraArguments extra_args);
    337   static void Generate_CompileUnoptimized(MacroAssembler* masm);
    338   static void Generate_InOptimizationQueue(MacroAssembler* masm);
    339   static void Generate_CompileOptimized(MacroAssembler* masm);
    340   static void Generate_CompileOptimizedConcurrent(MacroAssembler* masm);
    341   static void Generate_JSConstructStubGeneric(MacroAssembler* masm);
    342   static void Generate_JSConstructStubApi(MacroAssembler* masm);
    343   static void Generate_JSEntryTrampoline(MacroAssembler* masm);
    344   static void Generate_JSConstructEntryTrampoline(MacroAssembler* masm);
    345   static void Generate_NotifyDeoptimized(MacroAssembler* masm);
    346   static void Generate_NotifySoftDeoptimized(MacroAssembler* masm);
    347   static void Generate_NotifyLazyDeoptimized(MacroAssembler* masm);
    348   static void Generate_NotifyStubFailure(MacroAssembler* masm);
    349   static void Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm);
    350   static void Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm);
    351 
    352   static void Generate_FunctionCall(MacroAssembler* masm);
    353   static void Generate_FunctionApply(MacroAssembler* masm);
    354 
    355   static void Generate_InternalArrayCode(MacroAssembler* masm);
    356   static void Generate_ArrayCode(MacroAssembler* masm);
    357 
    358   static void Generate_StringConstructCode(MacroAssembler* masm);
    359   static void Generate_OnStackReplacement(MacroAssembler* masm);
    360   static void Generate_OsrAfterStackCheck(MacroAssembler* masm);
    361   static void Generate_InterruptCheck(MacroAssembler* masm);
    362   static void Generate_StackCheck(MacroAssembler* masm);
    363 
    364 #define DECLARE_CODE_AGE_BUILTIN_GENERATOR(C)                \
    365   static void Generate_Make##C##CodeYoungAgainEvenMarking(   \
    366       MacroAssembler* masm);                                 \
    367   static void Generate_Make##C##CodeYoungAgainOddMarking(    \
    368       MacroAssembler* masm);
    369   CODE_AGE_LIST(DECLARE_CODE_AGE_BUILTIN_GENERATOR)
    370 #undef DECLARE_CODE_AGE_BUILTIN_GENERATOR
    371 
    372   static void Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm);
    373   static void Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm);
    374 
    375   static void InitBuiltinFunctionTable();
    376 
    377   bool initialized_;
    378 
    379   friend class BuiltinFunctionTable;
    380   friend class Isolate;
    381 
    382   DISALLOW_COPY_AND_ASSIGN(Builtins);
    383 };
    384 
    385 } }  // namespace v8::internal
    386 
    387 #endif  // V8_BUILTINS_H_
    388