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