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, kNoExtraICState) \ 68 V(InOptimizationQueue, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 69 V(JSConstructStubGeneric, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 70 V(JSConstructStubApi, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 71 V(JSEntryTrampoline, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 72 V(JSConstructEntryTrampoline, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 73 V(CompileLazy, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 74 V(CompileOptimized, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 75 V(CompileOptimizedConcurrent, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 76 V(NotifyDeoptimized, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 77 V(NotifySoftDeoptimized, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 78 V(NotifyLazyDeoptimized, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 79 V(NotifyStubFailure, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 80 V(NotifyStubFailureSaveDoubles, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 81 \ 82 V(LoadIC_Miss, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 83 V(KeyedLoadIC_Miss, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 84 V(StoreIC_Miss, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 85 V(KeyedStoreIC_Miss, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 86 V(LoadIC_Getter_ForDeopt, LOAD_IC, MONOMORPHIC, kNoExtraICState) \ 87 V(KeyedLoadIC_Initialize, KEYED_LOAD_IC, UNINITIALIZED, kNoExtraICState) \ 88 V(KeyedLoadIC_PreMonomorphic, KEYED_LOAD_IC, PREMONOMORPHIC, \ 89 kNoExtraICState) \ 90 V(KeyedLoadIC_Generic, KEYED_LOAD_IC, GENERIC, kNoExtraICState) \ 91 V(KeyedLoadIC_String, KEYED_LOAD_IC, MEGAMORPHIC, kNoExtraICState) \ 92 \ 93 V(StoreIC_Setter_ForDeopt, STORE_IC, MONOMORPHIC, StoreIC::kStrictModeState) \ 94 \ 95 V(KeyedStoreIC_Initialize, KEYED_STORE_IC, UNINITIALIZED, kNoExtraICState) \ 96 V(KeyedStoreIC_PreMonomorphic, KEYED_STORE_IC, PREMONOMORPHIC, \ 97 kNoExtraICState) \ 98 V(KeyedStoreIC_Generic, KEYED_STORE_IC, GENERIC, kNoExtraICState) \ 99 \ 100 V(KeyedStoreIC_Initialize_Strict, KEYED_STORE_IC, UNINITIALIZED, \ 101 StoreIC::kStrictModeState) \ 102 V(KeyedStoreIC_PreMonomorphic_Strict, KEYED_STORE_IC, PREMONOMORPHIC, \ 103 StoreIC::kStrictModeState) \ 104 V(KeyedStoreIC_Generic_Strict, KEYED_STORE_IC, GENERIC, \ 105 StoreIC::kStrictModeState) \ 106 V(KeyedStoreIC_SloppyArguments, KEYED_STORE_IC, MONOMORPHIC, \ 107 kNoExtraICState) \ 108 \ 109 /* Uses KeyedLoadIC_Initialize; must be after in list. */ \ 110 V(FunctionCall, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 111 V(FunctionApply, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 112 \ 113 V(InternalArrayCode, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 114 V(ArrayCode, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 115 \ 116 V(StringConstructCode, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 117 \ 118 V(OnStackReplacement, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 119 V(InterruptCheck, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 120 V(OsrAfterStackCheck, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 121 V(StackCheck, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 122 \ 123 V(MarkCodeAsExecutedOnce, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 124 V(MarkCodeAsExecutedTwice, BUILTIN, UNINITIALIZED, kNoExtraICState) \ 125 CODE_AGE_LIST_WITH_ARG(DECLARE_CODE_AGE_BUILTIN, V) 126 127 // Define list of builtin handlers implemented in assembly. 128 #define BUILTIN_LIST_H(V) \ 129 V(LoadIC_Slow, LOAD_IC) \ 130 V(KeyedLoadIC_Slow, KEYED_LOAD_IC) \ 131 V(StoreIC_Slow, STORE_IC) \ 132 V(KeyedStoreIC_Slow, KEYED_STORE_IC) \ 133 V(LoadIC_Normal, LOAD_IC) \ 134 V(StoreIC_Normal, STORE_IC) 135 136 // Define list of builtins used by the debugger implemented in assembly. 137 #define BUILTIN_LIST_DEBUG_A(V) \ 138 V(Return_DebugBreak, BUILTIN, DEBUG_STUB, \ 139 DEBUG_BREAK) \ 140 V(CallFunctionStub_DebugBreak, BUILTIN, DEBUG_STUB, \ 141 DEBUG_BREAK) \ 142 V(CallConstructStub_DebugBreak, BUILTIN, DEBUG_STUB, \ 143 DEBUG_BREAK) \ 144 V(CallConstructStub_Recording_DebugBreak, BUILTIN, DEBUG_STUB, \ 145 DEBUG_BREAK) \ 146 V(CallICStub_DebugBreak, CALL_IC, DEBUG_STUB, \ 147 DEBUG_BREAK) \ 148 V(LoadIC_DebugBreak, LOAD_IC, DEBUG_STUB, \ 149 DEBUG_BREAK) \ 150 V(KeyedLoadIC_DebugBreak, KEYED_LOAD_IC, DEBUG_STUB, \ 151 DEBUG_BREAK) \ 152 V(StoreIC_DebugBreak, STORE_IC, DEBUG_STUB, \ 153 DEBUG_BREAK) \ 154 V(KeyedStoreIC_DebugBreak, KEYED_STORE_IC, DEBUG_STUB, \ 155 DEBUG_BREAK) \ 156 V(CompareNilIC_DebugBreak, COMPARE_NIL_IC, DEBUG_STUB, \ 157 DEBUG_BREAK) \ 158 V(Slot_DebugBreak, BUILTIN, DEBUG_STUB, \ 159 DEBUG_BREAK) \ 160 V(PlainReturn_LiveEdit, BUILTIN, DEBUG_STUB, \ 161 DEBUG_BREAK) \ 162 V(FrameDropper_LiveEdit, BUILTIN, DEBUG_STUB, \ 163 DEBUG_BREAK) 164 165 // Define list of builtins implemented in JavaScript. 166 #define BUILTINS_LIST_JS(V) \ 167 V(EQUALS, 1) \ 168 V(STRICT_EQUALS, 1) \ 169 V(COMPARE, 2) \ 170 V(ADD, 1) \ 171 V(SUB, 1) \ 172 V(MUL, 1) \ 173 V(DIV, 1) \ 174 V(MOD, 1) \ 175 V(BIT_OR, 1) \ 176 V(BIT_AND, 1) \ 177 V(BIT_XOR, 1) \ 178 V(SHL, 1) \ 179 V(SAR, 1) \ 180 V(SHR, 1) \ 181 V(DELETE, 2) \ 182 V(IN, 1) \ 183 V(INSTANCE_OF, 1) \ 184 V(FILTER_KEY, 1) \ 185 V(CALL_NON_FUNCTION, 0) \ 186 V(CALL_NON_FUNCTION_AS_CONSTRUCTOR, 0) \ 187 V(CALL_FUNCTION_PROXY, 1) \ 188 V(CALL_FUNCTION_PROXY_AS_CONSTRUCTOR, 1) \ 189 V(TO_OBJECT, 0) \ 190 V(TO_NUMBER, 0) \ 191 V(TO_STRING, 0) \ 192 V(STRING_ADD_LEFT, 1) \ 193 V(STRING_ADD_RIGHT, 1) \ 194 V(APPLY_PREPARE, 1) \ 195 V(STACK_OVERFLOW, 1) 196 197 class BuiltinFunctionTable; 198 class ObjectVisitor; 199 200 201 class Builtins { 202 public: 203 ~Builtins(); 204 205 // Generate all builtin code objects. Should be called once during 206 // isolate initialization. 207 void SetUp(Isolate* isolate, bool create_heap_objects); 208 void TearDown(); 209 210 // Garbage collection support. 211 void IterateBuiltins(ObjectVisitor* v); 212 213 // Disassembler support. 214 const char* Lookup(byte* pc); 215 216 enum Name { 217 #define DEF_ENUM_C(name, ignore) k##name, 218 #define DEF_ENUM_A(name, kind, state, extra) k##name, 219 #define DEF_ENUM_H(name, kind) k##name, 220 BUILTIN_LIST_C(DEF_ENUM_C) 221 BUILTIN_LIST_A(DEF_ENUM_A) 222 BUILTIN_LIST_H(DEF_ENUM_H) 223 BUILTIN_LIST_DEBUG_A(DEF_ENUM_A) 224 #undef DEF_ENUM_C 225 #undef DEF_ENUM_A 226 builtin_count 227 }; 228 229 enum CFunctionId { 230 #define DEF_ENUM_C(name, ignore) c_##name, 231 BUILTIN_LIST_C(DEF_ENUM_C) 232 #undef DEF_ENUM_C 233 cfunction_count 234 }; 235 236 enum JavaScript { 237 #define DEF_ENUM(name, ignore) name, 238 BUILTINS_LIST_JS(DEF_ENUM) 239 #undef DEF_ENUM 240 id_count 241 }; 242 243 #define DECLARE_BUILTIN_ACCESSOR_C(name, ignore) Handle<Code> name(); 244 #define DECLARE_BUILTIN_ACCESSOR_A(name, kind, state, extra) \ 245 Handle<Code> name(); 246 #define DECLARE_BUILTIN_ACCESSOR_H(name, kind) Handle<Code> name(); 247 BUILTIN_LIST_C(DECLARE_BUILTIN_ACCESSOR_C) BUILTIN_LIST_A(DECLARE_BUILTIN_ACCESSOR_A)248 BUILTIN_LIST_A(DECLARE_BUILTIN_ACCESSOR_A) 249 BUILTIN_LIST_H(DECLARE_BUILTIN_ACCESSOR_H) 250 BUILTIN_LIST_DEBUG_A(DECLARE_BUILTIN_ACCESSOR_A) 251 #undef DECLARE_BUILTIN_ACCESSOR_C 252 #undef DECLARE_BUILTIN_ACCESSOR_A 253 254 Code* builtin(Name name) { 255 // Code::cast cannot be used here since we access builtins 256 // during the marking phase of mark sweep. See IC::Clear. 257 return reinterpret_cast<Code*>(builtins_[name]); 258 } 259 builtin_address(Name name)260 Address builtin_address(Name name) { 261 return reinterpret_cast<Address>(&builtins_[name]); 262 } 263 c_function_address(CFunctionId id)264 static Address c_function_address(CFunctionId id) { 265 return c_functions_[id]; 266 } 267 GetName(JavaScript id)268 static const char* GetName(JavaScript id) { return javascript_names_[id]; } name(int index)269 const char* name(int index) { 270 DCHECK(index >= 0); 271 DCHECK(index < builtin_count); 272 return names_[index]; 273 } GetArgumentsCount(JavaScript id)274 static int GetArgumentsCount(JavaScript id) { return javascript_argc_[id]; } 275 Handle<Code> GetCode(JavaScript id, bool* resolved); NumberOfJavaScriptBuiltins()276 static int NumberOfJavaScriptBuiltins() { return id_count; } 277 is_initialized()278 bool is_initialized() const { return initialized_; } 279 280 private: 281 Builtins(); 282 283 // The external C++ functions called from the code. 284 static Address const c_functions_[cfunction_count]; 285 286 // Note: These are always Code objects, but to conform with 287 // IterateBuiltins() above which assumes Object**'s for the callback 288 // function f, we use an Object* array here. 289 Object* builtins_[builtin_count]; 290 const char* names_[builtin_count]; 291 static const char* const javascript_names_[id_count]; 292 static int const javascript_argc_[id_count]; 293 294 static void Generate_Adaptor(MacroAssembler* masm, 295 CFunctionId id, 296 BuiltinExtraArguments extra_args); 297 static void Generate_CompileLazy(MacroAssembler* masm); 298 static void Generate_InOptimizationQueue(MacroAssembler* masm); 299 static void Generate_CompileOptimized(MacroAssembler* masm); 300 static void Generate_CompileOptimizedConcurrent(MacroAssembler* masm); 301 static void Generate_JSConstructStubGeneric(MacroAssembler* masm); 302 static void Generate_JSConstructStubApi(MacroAssembler* masm); 303 static void Generate_JSEntryTrampoline(MacroAssembler* masm); 304 static void Generate_JSConstructEntryTrampoline(MacroAssembler* masm); 305 static void Generate_NotifyDeoptimized(MacroAssembler* masm); 306 static void Generate_NotifySoftDeoptimized(MacroAssembler* masm); 307 static void Generate_NotifyLazyDeoptimized(MacroAssembler* masm); 308 static void Generate_NotifyStubFailure(MacroAssembler* masm); 309 static void Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm); 310 static void Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm); 311 312 static void Generate_FunctionCall(MacroAssembler* masm); 313 static void Generate_FunctionApply(MacroAssembler* masm); 314 315 static void Generate_InternalArrayCode(MacroAssembler* masm); 316 static void Generate_ArrayCode(MacroAssembler* masm); 317 318 static void Generate_StringConstructCode(MacroAssembler* masm); 319 static void Generate_OnStackReplacement(MacroAssembler* masm); 320 static void Generate_OsrAfterStackCheck(MacroAssembler* masm); 321 static void Generate_InterruptCheck(MacroAssembler* masm); 322 static void Generate_StackCheck(MacroAssembler* masm); 323 324 #define DECLARE_CODE_AGE_BUILTIN_GENERATOR(C) \ 325 static void Generate_Make##C##CodeYoungAgainEvenMarking( \ 326 MacroAssembler* masm); \ 327 static void Generate_Make##C##CodeYoungAgainOddMarking( \ 328 MacroAssembler* masm); 329 CODE_AGE_LIST(DECLARE_CODE_AGE_BUILTIN_GENERATOR) 330 #undef DECLARE_CODE_AGE_BUILTIN_GENERATOR 331 332 static void Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm); 333 static void Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm); 334 335 static void InitBuiltinFunctionTable(); 336 337 bool initialized_; 338 339 friend class BuiltinFunctionTable; 340 friend class Isolate; 341 342 DISALLOW_COPY_AND_ASSIGN(Builtins); 343 }; 344 345 } } // namespace v8::internal 346 347 #endif // V8_BUILTINS_H_ 348