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