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) BUILTIN_LIST_A(DECLARE_BUILTIN_ACCESSOR_A)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 builtin_address(Name name)300 Address builtin_address(Name name) { 301 return reinterpret_cast<Address>(&builtins_[name]); 302 } 303 c_function_address(CFunctionId id)304 static Address c_function_address(CFunctionId id) { 305 return c_functions_[id]; 306 } 307 GetName(JavaScript id)308 static const char* GetName(JavaScript id) { return javascript_names_[id]; } name(int index)309 const char* name(int index) { 310 ASSERT(index >= 0); 311 ASSERT(index < builtin_count); 312 return names_[index]; 313 } GetArgumentsCount(JavaScript id)314 static int GetArgumentsCount(JavaScript id) { return javascript_argc_[id]; } 315 Handle<Code> GetCode(JavaScript id, bool* resolved); NumberOfJavaScriptBuiltins()316 static int NumberOfJavaScriptBuiltins() { return id_count; } 317 is_initialized()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