| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 | 82 |
| 83 Handle<Code> FindIC(Handle<Name> name, | 83 Handle<Code> FindIC(Handle<Name> name, |
| 84 Handle<Map> stub_holder_map, | 84 Handle<Map> stub_holder_map, |
| 85 Code::Kind kind, | 85 Code::Kind kind, |
| 86 ExtraICState extra_state = kNoExtraICState, | 86 ExtraICState extra_state = kNoExtraICState, |
| 87 InlineCacheHolderFlag cache_holder = OWN_MAP); | 87 InlineCacheHolderFlag cache_holder = OWN_MAP); |
| 88 | 88 |
| 89 Handle<Code> FindHandler(Handle<Name> name, | 89 Handle<Code> FindHandler(Handle<Name> name, |
| 90 Handle<Map> map, | 90 Handle<Map> map, |
| 91 Code::Kind kind, | 91 Code::Kind kind, |
| 92 InlineCacheHolderFlag cache_holder = OWN_MAP); | 92 InlineCacheHolderFlag cache_holder, |
| 93 Code::StubType type); |
| 93 | 94 |
| 94 Handle<Code> ComputeMonomorphicIC(Handle<Name> name, | 95 Handle<Code> ComputeMonomorphicIC(Code::Kind kind, |
| 95 Handle<Type> type, | 96 Handle<Name> name, |
| 97 Handle<HeapType> type, |
| 96 Handle<Code> handler, | 98 Handle<Code> handler, |
| 97 ExtraICState extra_ic_state); | 99 ExtraICState extra_ic_state); |
| 98 | 100 |
| 99 Handle<Code> ComputeLoadNonexistent(Handle<Name> name, Handle<Type> type); | 101 Handle<Code> ComputeLoadNonexistent(Handle<Name> name, Handle<HeapType> type); |
| 100 | 102 |
| 101 Handle<Code> ComputeKeyedLoadElement(Handle<Map> receiver_map); | 103 Handle<Code> ComputeKeyedLoadElement(Handle<Map> receiver_map); |
| 102 | 104 |
| 103 Handle<Code> ComputeKeyedStoreElement(Handle<Map> receiver_map, | 105 Handle<Code> ComputeKeyedStoreElement(Handle<Map> receiver_map, |
| 104 StrictModeFlag strict_mode, | 106 StrictModeFlag strict_mode, |
| 105 KeyedAccessStoreMode store_mode); | 107 KeyedAccessStoreMode store_mode); |
| 106 | 108 |
| 107 Handle<Code> ComputeCallField(int argc, | |
| 108 Code::Kind, | |
| 109 ExtraICState extra_state, | |
| 110 Handle<Name> name, | |
| 111 Handle<Object> object, | |
| 112 Handle<JSObject> holder, | |
| 113 PropertyIndex index); | |
| 114 | |
| 115 Handle<Code> ComputeCallConstant(int argc, | |
| 116 Code::Kind, | |
| 117 ExtraICState extra_state, | |
| 118 Handle<Name> name, | |
| 119 Handle<Object> object, | |
| 120 Handle<JSObject> holder, | |
| 121 Handle<JSFunction> function); | |
| 122 | |
| 123 Handle<Code> ComputeCallInterceptor(int argc, | |
| 124 Code::Kind, | |
| 125 ExtraICState extra_state, | |
| 126 Handle<Name> name, | |
| 127 Handle<Object> object, | |
| 128 Handle<JSObject> holder); | |
| 129 | |
| 130 Handle<Code> ComputeCallGlobal(int argc, | |
| 131 Code::Kind, | |
| 132 ExtraICState extra_state, | |
| 133 Handle<Name> name, | |
| 134 Handle<JSObject> object, | |
| 135 Handle<GlobalObject> holder, | |
| 136 Handle<PropertyCell> cell, | |
| 137 Handle<JSFunction> function); | |
| 138 | |
| 139 // --- | |
| 140 | |
| 141 Handle<Code> ComputeCallInitialize(int argc); | |
| 142 | |
| 143 Handle<Code> ComputeKeyedCallInitialize(int argc); | |
| 144 | |
| 145 Handle<Code> ComputeCallPreMonomorphic(int argc, | |
| 146 Code::Kind kind, | |
| 147 ExtraICState extra_state); | |
| 148 | |
| 149 Handle<Code> ComputeCallNormal(int argc, | |
| 150 Code::Kind kind, | |
| 151 ExtraICState state); | |
| 152 | |
| 153 Handle<Code> ComputeCallArguments(int argc); | |
| 154 | |
| 155 Handle<Code> ComputeCallMegamorphic(int argc, | |
| 156 Code::Kind kind, | |
| 157 ExtraICState state); | |
| 158 | |
| 159 Handle<Code> ComputeCallMiss(int argc, | |
| 160 Code::Kind kind, | |
| 161 ExtraICState state); | |
| 162 | |
| 163 // --- | 109 // --- |
| 164 | 110 |
| 165 Handle<Code> ComputeLoad(InlineCacheState ic_state, ExtraICState extra_state); | 111 Handle<Code> ComputeLoad(InlineCacheState ic_state, ExtraICState extra_state); |
| 166 Handle<Code> ComputeStore(InlineCacheState ic_state, | 112 Handle<Code> ComputeStore(InlineCacheState ic_state, |
| 167 ExtraICState extra_state); | 113 ExtraICState extra_state); |
| 168 | 114 |
| 169 // --- | 115 // --- |
| 170 | 116 |
| 171 Handle<Code> ComputeCompareNil(Handle<Map> receiver_map, | 117 Handle<Code> ComputeCompareNil(Handle<Map> receiver_map, |
| 172 CompareNilICStub& stub); | 118 CompareNilICStub& stub); |
| 173 | 119 |
| 174 // --- | 120 // --- |
| 175 | 121 |
| 176 Handle<Code> ComputeLoadElementPolymorphic(MapHandleList* receiver_maps); | 122 Handle<Code> ComputeLoadElementPolymorphic(MapHandleList* receiver_maps); |
| 177 Handle<Code> ComputeStoreElementPolymorphic(MapHandleList* receiver_maps, | 123 Handle<Code> ComputeStoreElementPolymorphic(MapHandleList* receiver_maps, |
| 178 KeyedAccessStoreMode store_mode, | 124 KeyedAccessStoreMode store_mode, |
| 179 StrictModeFlag strict_mode); | 125 StrictModeFlag strict_mode); |
| 180 | 126 |
| 181 Handle<Code> ComputePolymorphicIC(TypeHandleList* types, | 127 Handle<Code> ComputePolymorphicIC(Code::Kind kind, |
| 128 TypeHandleList* types, |
| 182 CodeHandleList* handlers, | 129 CodeHandleList* handlers, |
| 183 int number_of_valid_maps, | 130 int number_of_valid_maps, |
| 184 Handle<Name> name, | 131 Handle<Name> name, |
| 185 ExtraICState extra_ic_state); | 132 ExtraICState extra_ic_state); |
| 186 | 133 |
| 187 // Finds the Code object stored in the Heap::non_monomorphic_cache(). | 134 // Finds the Code object stored in the Heap::non_monomorphic_cache(). |
| 188 Code* FindCallInitialize(int argc, Code::Kind kind); | |
| 189 Code* FindPreMonomorphicIC(Code::Kind kind, ExtraICState extra_ic_state); | 135 Code* FindPreMonomorphicIC(Code::Kind kind, ExtraICState extra_ic_state); |
| 190 | 136 |
| 191 #ifdef ENABLE_DEBUGGER_SUPPORT | |
| 192 Handle<Code> ComputeCallDebugBreak(int argc, Code::Kind kind); | |
| 193 | |
| 194 Handle<Code> ComputeCallDebugPrepareStepIn(int argc, Code::Kind kind); | |
| 195 #endif | |
| 196 | |
| 197 // Update cache for entry hash(name, map). | 137 // Update cache for entry hash(name, map). |
| 198 Code* Set(Name* name, Map* map, Code* code); | 138 Code* Set(Name* name, Map* map, Code* code); |
| 199 | 139 |
| 200 // Clear the lookup table (@ mark compact collection). | 140 // Clear the lookup table (@ mark compact collection). |
| 201 void Clear(); | 141 void Clear(); |
| 202 | 142 |
| 203 // Collect all maps that match the name and flags. | 143 // Collect all maps that match the name and flags. |
| 204 void CollectMatchingMaps(SmallMapList* types, | 144 void CollectMatchingMaps(SmallMapList* types, |
| 205 Handle<Name> name, | 145 Handle<Name> name, |
| 206 Code::Flags flags, | 146 Code::Flags flags, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 // LoadWithInterceptor. | 202 // LoadWithInterceptor. |
| 263 static const int kInterceptorArgsNameIndex = 0; | 203 static const int kInterceptorArgsNameIndex = 0; |
| 264 static const int kInterceptorArgsInfoIndex = 1; | 204 static const int kInterceptorArgsInfoIndex = 1; |
| 265 static const int kInterceptorArgsThisIndex = 2; | 205 static const int kInterceptorArgsThisIndex = 2; |
| 266 static const int kInterceptorArgsHolderIndex = 3; | 206 static const int kInterceptorArgsHolderIndex = 3; |
| 267 static const int kInterceptorArgsLength = 4; | 207 static const int kInterceptorArgsLength = 4; |
| 268 | 208 |
| 269 private: | 209 private: |
| 270 explicit StubCache(Isolate* isolate); | 210 explicit StubCache(Isolate* isolate); |
| 271 | 211 |
| 272 Handle<Code> ComputeCallInitialize(int argc, Code::Kind kind); | |
| 273 | |
| 274 // The stub cache has a primary and secondary level. The two levels have | 212 // The stub cache has a primary and secondary level. The two levels have |
| 275 // different hashing algorithms in order to avoid simultaneous collisions | 213 // different hashing algorithms in order to avoid simultaneous collisions |
| 276 // in both caches. Unlike a probing strategy (quadratic or otherwise) the | 214 // in both caches. Unlike a probing strategy (quadratic or otherwise) the |
| 277 // update strategy on updates is fairly clear and simple: Any existing entry | 215 // update strategy on updates is fairly clear and simple: Any existing entry |
| 278 // in the primary cache is moved to the secondary cache, and secondary cache | 216 // in the primary cache is moved to the secondary cache, and secondary cache |
| 279 // entries are overwritten. | 217 // entries are overwritten. |
| 280 | 218 |
| 281 // Hash algorithm for the primary table. This algorithm is replicated in | 219 // Hash algorithm for the primary table. This algorithm is replicated in |
| 282 // assembler for every architecture. Returns an index into the table that | 220 // assembler for every architecture. Returns an index into the table that |
| 283 // is scaled by 1 << kHeapObjectTagSize. | 221 // is scaled by 1 << kHeapObjectTagSize. |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 | 289 |
| 352 // Support functions for IC stubs for callbacks. | 290 // Support functions for IC stubs for callbacks. |
| 353 DECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreCallbackProperty); | 291 DECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreCallbackProperty); |
| 354 | 292 |
| 355 | 293 |
| 356 // Support functions for IC stubs for interceptors. | 294 // Support functions for IC stubs for interceptors. |
| 357 DECLARE_RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorOnly); | 295 DECLARE_RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorOnly); |
| 358 DECLARE_RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForLoad); | 296 DECLARE_RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForLoad); |
| 359 DECLARE_RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForCall); | 297 DECLARE_RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForCall); |
| 360 DECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty); | 298 DECLARE_RUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty); |
| 361 DECLARE_RUNTIME_FUNCTION(MaybeObject*, CallInterceptorProperty); | |
| 362 DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor); | 299 DECLARE_RUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor); |
| 363 | 300 |
| 364 | 301 |
| 365 enum PrototypeCheckType { CHECK_ALL_MAPS, SKIP_RECEIVER }; | 302 enum PrototypeCheckType { CHECK_ALL_MAPS, SKIP_RECEIVER }; |
| 366 enum IcCheckType { ELEMENT, PROPERTY }; | 303 enum IcCheckType { ELEMENT, PROPERTY }; |
| 367 | 304 |
| 368 | 305 |
| 369 // The stub compilers compile stubs for the stub cache. | 306 // The stub compilers compile stubs for the stub cache. |
| 370 class StubCompiler BASE_EMBEDDED { | 307 class StubCompiler BASE_EMBEDDED { |
| 371 public: | 308 public: |
| 372 explicit StubCompiler(Isolate* isolate, | 309 explicit StubCompiler(Isolate* isolate, |
| 373 ExtraICState extra_ic_state = kNoExtraICState) | 310 ExtraICState extra_ic_state = kNoExtraICState) |
| 374 : isolate_(isolate), extra_ic_state_(extra_ic_state), | 311 : isolate_(isolate), extra_ic_state_(extra_ic_state), |
| 375 masm_(isolate, NULL, 256), failure_(NULL) { } | 312 masm_(isolate, NULL, 256), failure_(NULL) { } |
| 376 | 313 |
| 377 // Functions to compile either CallIC or KeyedCallIC. The specific kind | |
| 378 // is extracted from the code flags. | |
| 379 Handle<Code> CompileCallInitialize(Code::Flags flags); | |
| 380 Handle<Code> CompileCallPreMonomorphic(Code::Flags flags); | |
| 381 Handle<Code> CompileCallNormal(Code::Flags flags); | |
| 382 Handle<Code> CompileCallMegamorphic(Code::Flags flags); | |
| 383 Handle<Code> CompileCallArguments(Code::Flags flags); | |
| 384 Handle<Code> CompileCallMiss(Code::Flags flags); | |
| 385 | |
| 386 Handle<Code> CompileLoadInitialize(Code::Flags flags); | 314 Handle<Code> CompileLoadInitialize(Code::Flags flags); |
| 387 Handle<Code> CompileLoadPreMonomorphic(Code::Flags flags); | 315 Handle<Code> CompileLoadPreMonomorphic(Code::Flags flags); |
| 388 Handle<Code> CompileLoadMegamorphic(Code::Flags flags); | 316 Handle<Code> CompileLoadMegamorphic(Code::Flags flags); |
| 389 | 317 |
| 390 Handle<Code> CompileStoreInitialize(Code::Flags flags); | 318 Handle<Code> CompileStoreInitialize(Code::Flags flags); |
| 391 Handle<Code> CompileStorePreMonomorphic(Code::Flags flags); | 319 Handle<Code> CompileStorePreMonomorphic(Code::Flags flags); |
| 392 Handle<Code> CompileStoreGeneric(Code::Flags flags); | 320 Handle<Code> CompileStoreGeneric(Code::Flags flags); |
| 393 Handle<Code> CompileStoreMegamorphic(Code::Flags flags); | 321 Handle<Code> CompileStoreMegamorphic(Code::Flags flags); |
| 394 | 322 |
| 395 #ifdef ENABLE_DEBUGGER_SUPPORT | |
| 396 Handle<Code> CompileCallDebugBreak(Code::Flags flags); | |
| 397 Handle<Code> CompileCallDebugPrepareStepIn(Code::Flags flags); | |
| 398 #endif | |
| 399 | |
| 400 // Static functions for generating parts of stubs. | 323 // Static functions for generating parts of stubs. |
| 401 static void GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, | 324 static void GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, |
| 402 int index, | 325 int index, |
| 403 Register prototype); | 326 Register prototype); |
| 404 | 327 |
| 405 // Helper function used to check that the dictionary doesn't contain | 328 // Helper function used to check that the dictionary doesn't contain |
| 406 // the property. This function may return false negatives, so miss_label | 329 // the property. This function may return false negatives, so miss_label |
| 407 // must always call a backup property check that is complete. | 330 // must always call a backup property check that is complete. |
| 408 // This function is safe to call if the receiver has fast properties. | 331 // This function is safe to call if the receiver has fast properties. |
| 409 // Name must be unique and receiver must be a heap object. | 332 // Name must be unique and receiver must be a heap object. |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 // objects or doing negative lookup for slow objects, ensures that the | 388 // objects or doing negative lookup for slow objects, ensures that the |
| 466 // property cells for global objects are still empty) and checks that the map | 389 // property cells for global objects are still empty) and checks that the map |
| 467 // of the holder has not changed. If necessary the function also generates | 390 // of the holder has not changed. If necessary the function also generates |
| 468 // code for security check in case of global object holders. Helps to make | 391 // code for security check in case of global object holders. Helps to make |
| 469 // sure that the current IC is still valid. | 392 // sure that the current IC is still valid. |
| 470 // | 393 // |
| 471 // The scratch and holder registers are always clobbered, but the object | 394 // The scratch and holder registers are always clobbered, but the object |
| 472 // register is only clobbered if it the same as the holder register. The | 395 // register is only clobbered if it the same as the holder register. The |
| 473 // function returns a register containing the holder - either object_reg or | 396 // function returns a register containing the holder - either object_reg or |
| 474 // holder_reg. | 397 // holder_reg. |
| 475 // The function can optionally (when save_at_depth != | 398 Register CheckPrototypes(Handle<HeapType> type, |
| 476 // kInvalidProtoDepth) save the object at the given depth by moving | |
| 477 // it to [esp + kPointerSize]. | |
| 478 Register CheckPrototypes(Handle<Type> type, | |
| 479 Register object_reg, | 399 Register object_reg, |
| 480 Handle<JSObject> holder, | 400 Handle<JSObject> holder, |
| 481 Register holder_reg, | 401 Register holder_reg, |
| 482 Register scratch1, | 402 Register scratch1, |
| 483 Register scratch2, | 403 Register scratch2, |
| 484 Handle<Name> name, | 404 Handle<Name> name, |
| 485 Label* miss, | 405 Label* miss, |
| 486 PrototypeCheckType check = CHECK_ALL_MAPS) { | |
| 487 return CheckPrototypes(type, object_reg, holder, holder_reg, scratch1, | |
| 488 scratch2, name, kInvalidProtoDepth, miss, check); | |
| 489 } | |
| 490 | |
| 491 Register CheckPrototypes(Handle<Type> type, | |
| 492 Register object_reg, | |
| 493 Handle<JSObject> holder, | |
| 494 Register holder_reg, | |
| 495 Register scratch1, | |
| 496 Register scratch2, | |
| 497 Handle<Name> name, | |
| 498 int save_at_depth, | |
| 499 Label* miss, | |
| 500 PrototypeCheckType check = CHECK_ALL_MAPS); | 406 PrototypeCheckType check = CHECK_ALL_MAPS); |
| 501 | 407 |
| 502 void GenerateBooleanCheck(Register object, Label* miss); | 408 void GenerateBooleanCheck(Register object, Label* miss); |
| 503 | 409 |
| 410 static void GenerateFastApiCall(MacroAssembler* masm, |
| 411 const CallOptimization& optimization, |
| 412 Handle<Map> receiver_map, |
| 413 Register receiver, |
| 414 Register scratch, |
| 415 bool is_store, |
| 416 int argc, |
| 417 Register* values); |
| 418 |
| 504 protected: | 419 protected: |
| 505 Handle<Code> GetCodeWithFlags(Code::Flags flags, const char* name); | 420 Handle<Code> GetCodeWithFlags(Code::Flags flags, const char* name); |
| 506 Handle<Code> GetCodeWithFlags(Code::Flags flags, Handle<Name> name); | 421 Handle<Code> GetCodeWithFlags(Code::Flags flags, Handle<Name> name); |
| 507 | 422 |
| 508 ExtraICState extra_state() { return extra_ic_state_; } | 423 ExtraICState extra_state() { return extra_ic_state_; } |
| 509 | 424 |
| 510 MacroAssembler* masm() { return &masm_; } | 425 MacroAssembler* masm() { return &masm_; } |
| 511 void set_failure(Failure* failure) { failure_ = failure; } | 426 void set_failure(Failure* failure) { failure_ = failure; } |
| 512 | 427 |
| 513 static void LookupPostInterceptor(Handle<JSObject> holder, | 428 static void LookupPostInterceptor(Handle<JSObject> holder, |
| (...skipping 23 matching lines...) Expand all Loading... |
| 537 Code::Kind kind, | 452 Code::Kind kind, |
| 538 ExtraICState extra_ic_state = kNoExtraICState, | 453 ExtraICState extra_ic_state = kNoExtraICState, |
| 539 InlineCacheHolderFlag cache_holder = OWN_MAP) | 454 InlineCacheHolderFlag cache_holder = OWN_MAP) |
| 540 : StubCompiler(isolate, extra_ic_state), | 455 : StubCompiler(isolate, extra_ic_state), |
| 541 kind_(kind), | 456 kind_(kind), |
| 542 cache_holder_(cache_holder) { | 457 cache_holder_(cache_holder) { |
| 543 InitializeRegisters(); | 458 InitializeRegisters(); |
| 544 } | 459 } |
| 545 virtual ~BaseLoadStoreStubCompiler() { } | 460 virtual ~BaseLoadStoreStubCompiler() { } |
| 546 | 461 |
| 547 Handle<Code> CompileMonomorphicIC(Handle<Type> type, | 462 Handle<Code> CompileMonomorphicIC(Handle<HeapType> type, |
| 548 Handle<Code> handler, | 463 Handle<Code> handler, |
| 549 Handle<Name> name); | 464 Handle<Name> name); |
| 550 | 465 |
| 551 Handle<Code> CompilePolymorphicIC(TypeHandleList* types, | 466 Handle<Code> CompilePolymorphicIC(TypeHandleList* types, |
| 552 CodeHandleList* handlers, | 467 CodeHandleList* handlers, |
| 553 Handle<Name> name, | 468 Handle<Name> name, |
| 554 Code::StubType type, | 469 Code::StubType type, |
| 555 IcCheckType check); | 470 IcCheckType check); |
| 556 | 471 |
| 557 static Builtins::Name MissBuiltin(Code::Kind kind) { | 472 static Builtins::Name MissBuiltin(Code::Kind kind) { |
| 558 switch (kind) { | 473 switch (kind) { |
| 559 case Code::LOAD_IC: return Builtins::kLoadIC_Miss; | 474 case Code::LOAD_IC: return Builtins::kLoadIC_Miss; |
| 560 case Code::STORE_IC: return Builtins::kStoreIC_Miss; | 475 case Code::STORE_IC: return Builtins::kStoreIC_Miss; |
| 561 case Code::KEYED_LOAD_IC: return Builtins::kKeyedLoadIC_Miss; | 476 case Code::KEYED_LOAD_IC: return Builtins::kKeyedLoadIC_Miss; |
| 562 case Code::KEYED_STORE_IC: return Builtins::kKeyedStoreIC_Miss; | 477 case Code::KEYED_STORE_IC: return Builtins::kKeyedStoreIC_Miss; |
| 563 default: UNREACHABLE(); | 478 default: UNREACHABLE(); |
| 564 } | 479 } |
| 565 return Builtins::kLoadIC_Miss; | 480 return Builtins::kLoadIC_Miss; |
| 566 } | 481 } |
| 567 | 482 |
| 568 protected: | 483 protected: |
| 569 virtual Register HandlerFrontendHeader(Handle<Type> type, | 484 virtual Register HandlerFrontendHeader(Handle<HeapType> type, |
| 570 Register object_reg, | 485 Register object_reg, |
| 571 Handle<JSObject> holder, | 486 Handle<JSObject> holder, |
| 572 Handle<Name> name, | 487 Handle<Name> name, |
| 573 Label* miss) = 0; | 488 Label* miss) = 0; |
| 574 | 489 |
| 575 virtual void HandlerFrontendFooter(Handle<Name> name, Label* miss) = 0; | 490 virtual void HandlerFrontendFooter(Handle<Name> name, Label* miss) = 0; |
| 576 | 491 |
| 577 Register HandlerFrontend(Handle<Type> type, | 492 Register HandlerFrontend(Handle<HeapType> type, |
| 578 Register object_reg, | 493 Register object_reg, |
| 579 Handle<JSObject> holder, | 494 Handle<JSObject> holder, |
| 580 Handle<Name> name); | 495 Handle<Name> name); |
| 581 | 496 |
| 582 Handle<Code> GetCode(Code::Kind kind, | 497 Handle<Code> GetCode(Code::Kind kind, |
| 583 Code::StubType type, | 498 Code::StubType type, |
| 584 Handle<Name> name); | 499 Handle<Name> name); |
| 585 | 500 |
| 586 Handle<Code> GetICCode(Code::Kind kind, | 501 Handle<Code> GetICCode(Code::Kind kind, |
| 587 Code::StubType type, | 502 Code::StubType type, |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 626 class LoadStubCompiler: public BaseLoadStoreStubCompiler { | 541 class LoadStubCompiler: public BaseLoadStoreStubCompiler { |
| 627 public: | 542 public: |
| 628 LoadStubCompiler(Isolate* isolate, | 543 LoadStubCompiler(Isolate* isolate, |
| 629 ExtraICState extra_ic_state = kNoExtraICState, | 544 ExtraICState extra_ic_state = kNoExtraICState, |
| 630 InlineCacheHolderFlag cache_holder = OWN_MAP, | 545 InlineCacheHolderFlag cache_holder = OWN_MAP, |
| 631 Code::Kind kind = Code::LOAD_IC) | 546 Code::Kind kind = Code::LOAD_IC) |
| 632 : BaseLoadStoreStubCompiler(isolate, kind, extra_ic_state, | 547 : BaseLoadStoreStubCompiler(isolate, kind, extra_ic_state, |
| 633 cache_holder) { } | 548 cache_holder) { } |
| 634 virtual ~LoadStubCompiler() { } | 549 virtual ~LoadStubCompiler() { } |
| 635 | 550 |
| 636 Handle<Code> CompileLoadField(Handle<Type> type, | 551 Handle<Code> CompileLoadField(Handle<HeapType> type, |
| 637 Handle<JSObject> holder, | 552 Handle<JSObject> holder, |
| 638 Handle<Name> name, | 553 Handle<Name> name, |
| 639 PropertyIndex index, | 554 PropertyIndex index, |
| 640 Representation representation); | 555 Representation representation); |
| 641 | 556 |
| 642 Handle<Code> CompileLoadCallback(Handle<Type> type, | 557 Handle<Code> CompileLoadCallback(Handle<HeapType> type, |
| 643 Handle<JSObject> holder, | 558 Handle<JSObject> holder, |
| 644 Handle<Name> name, | 559 Handle<Name> name, |
| 645 Handle<ExecutableAccessorInfo> callback); | 560 Handle<ExecutableAccessorInfo> callback); |
| 646 | 561 |
| 647 Handle<Code> CompileLoadCallback(Handle<Type> type, | 562 Handle<Code> CompileLoadCallback(Handle<HeapType> type, |
| 648 Handle<JSObject> holder, | 563 Handle<JSObject> holder, |
| 649 Handle<Name> name, | 564 Handle<Name> name, |
| 650 const CallOptimization& call_optimization); | 565 const CallOptimization& call_optimization); |
| 651 | 566 |
| 652 Handle<Code> CompileLoadConstant(Handle<Type> type, | 567 Handle<Code> CompileLoadConstant(Handle<HeapType> type, |
| 653 Handle<JSObject> holder, | 568 Handle<JSObject> holder, |
| 654 Handle<Name> name, | 569 Handle<Name> name, |
| 655 Handle<Object> value); | 570 Handle<Object> value); |
| 656 | 571 |
| 657 Handle<Code> CompileLoadInterceptor(Handle<Type> type, | 572 Handle<Code> CompileLoadInterceptor(Handle<HeapType> type, |
| 658 Handle<JSObject> holder, | 573 Handle<JSObject> holder, |
| 659 Handle<Name> name); | 574 Handle<Name> name); |
| 660 | 575 |
| 661 Handle<Code> CompileLoadViaGetter(Handle<Type> type, | 576 Handle<Code> CompileLoadViaGetter(Handle<HeapType> type, |
| 662 Handle<JSObject> holder, | 577 Handle<JSObject> holder, |
| 663 Handle<Name> name, | 578 Handle<Name> name, |
| 664 Handle<JSFunction> getter); | 579 Handle<JSFunction> getter); |
| 665 | 580 |
| 666 static void GenerateLoadViaGetter(MacroAssembler* masm, | 581 static void GenerateLoadViaGetter(MacroAssembler* masm, |
| 582 Handle<HeapType> type, |
| 667 Register receiver, | 583 Register receiver, |
| 668 Handle<JSFunction> getter); | 584 Handle<JSFunction> getter); |
| 669 | 585 |
| 670 Handle<Code> CompileLoadNonexistent(Handle<Type> type, | 586 Handle<Code> CompileLoadNonexistent(Handle<HeapType> type, |
| 671 Handle<JSObject> last, | 587 Handle<JSObject> last, |
| 672 Handle<Name> name); | 588 Handle<Name> name); |
| 673 | 589 |
| 674 Handle<Code> CompileLoadGlobal(Handle<Type> type, | 590 Handle<Code> CompileLoadGlobal(Handle<HeapType> type, |
| 675 Handle<GlobalObject> holder, | 591 Handle<GlobalObject> holder, |
| 676 Handle<PropertyCell> cell, | 592 Handle<PropertyCell> cell, |
| 677 Handle<Name> name, | 593 Handle<Name> name, |
| 678 bool is_dont_delete); | 594 bool is_dont_delete); |
| 679 | 595 |
| 680 static Register* registers(); | 596 static Register* registers(); |
| 681 | 597 |
| 682 protected: | 598 protected: |
| 683 ContextualMode contextual_mode() { | 599 ContextualMode contextual_mode() { |
| 684 return LoadIC::GetContextualMode(extra_state()); | 600 return LoadIC::GetContextualMode(extra_state()); |
| 685 } | 601 } |
| 686 | 602 |
| 687 virtual Register HandlerFrontendHeader(Handle<Type> type, | 603 virtual Register HandlerFrontendHeader(Handle<HeapType> type, |
| 688 Register object_reg, | 604 Register object_reg, |
| 689 Handle<JSObject> holder, | 605 Handle<JSObject> holder, |
| 690 Handle<Name> name, | 606 Handle<Name> name, |
| 691 Label* miss); | 607 Label* miss); |
| 692 | 608 |
| 693 virtual void HandlerFrontendFooter(Handle<Name> name, Label* miss); | 609 virtual void HandlerFrontendFooter(Handle<Name> name, Label* miss); |
| 694 | 610 |
| 695 Register CallbackHandlerFrontend(Handle<Type> type, | 611 Register CallbackHandlerFrontend(Handle<HeapType> type, |
| 696 Register object_reg, | 612 Register object_reg, |
| 697 Handle<JSObject> holder, | 613 Handle<JSObject> holder, |
| 698 Handle<Name> name, | 614 Handle<Name> name, |
| 699 Handle<Object> callback); | 615 Handle<Object> callback); |
| 700 void NonexistentHandlerFrontend(Handle<Type> type, | 616 void NonexistentHandlerFrontend(Handle<HeapType> type, |
| 701 Handle<JSObject> last, | 617 Handle<JSObject> last, |
| 702 Handle<Name> name); | 618 Handle<Name> name); |
| 703 | 619 |
| 704 void GenerateLoadField(Register reg, | 620 void GenerateLoadField(Register reg, |
| 705 Handle<JSObject> holder, | 621 Handle<JSObject> holder, |
| 706 PropertyIndex field, | 622 PropertyIndex field, |
| 707 Representation representation); | 623 Representation representation); |
| 708 void GenerateLoadConstant(Handle<Object> value); | 624 void GenerateLoadConstant(Handle<Object> value); |
| 709 void GenerateLoadCallback(Register reg, | 625 void GenerateLoadCallback(Register reg, |
| 710 Handle<ExecutableAccessorInfo> callback); | 626 Handle<ExecutableAccessorInfo> callback); |
| 711 void GenerateLoadCallback(const CallOptimization& call_optimization); | 627 void GenerateLoadCallback(const CallOptimization& call_optimization, |
| 628 Handle<Map> receiver_map); |
| 712 void GenerateLoadInterceptor(Register holder_reg, | 629 void GenerateLoadInterceptor(Register holder_reg, |
| 713 Handle<Object> object, | 630 Handle<Object> object, |
| 714 Handle<JSObject> holder, | 631 Handle<JSObject> holder, |
| 715 LookupResult* lookup, | 632 LookupResult* lookup, |
| 716 Handle<Name> name); | 633 Handle<Name> name); |
| 717 void GenerateLoadPostInterceptor(Register reg, | 634 void GenerateLoadPostInterceptor(Register reg, |
| 718 Handle<JSObject> interceptor_holder, | 635 Handle<JSObject> interceptor_holder, |
| 719 Handle<Name> name, | 636 Handle<Name> name, |
| 720 LookupResult* lookup); | 637 LookupResult* lookup); |
| 721 | 638 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 Handle<JSObject> holder, | 718 Handle<JSObject> holder, |
| 802 Handle<Name> name, | 719 Handle<Name> name, |
| 803 Handle<ExecutableAccessorInfo> callback); | 720 Handle<ExecutableAccessorInfo> callback); |
| 804 | 721 |
| 805 Handle<Code> CompileStoreCallback(Handle<JSObject> object, | 722 Handle<Code> CompileStoreCallback(Handle<JSObject> object, |
| 806 Handle<JSObject> holder, | 723 Handle<JSObject> holder, |
| 807 Handle<Name> name, | 724 Handle<Name> name, |
| 808 const CallOptimization& call_optimization); | 725 const CallOptimization& call_optimization); |
| 809 | 726 |
| 810 static void GenerateStoreViaSetter(MacroAssembler* masm, | 727 static void GenerateStoreViaSetter(MacroAssembler* masm, |
| 728 Handle<HeapType> type, |
| 811 Handle<JSFunction> setter); | 729 Handle<JSFunction> setter); |
| 812 | 730 |
| 813 Handle<Code> CompileStoreViaSetter(Handle<JSObject> object, | 731 Handle<Code> CompileStoreViaSetter(Handle<JSObject> object, |
| 814 Handle<JSObject> holder, | 732 Handle<JSObject> holder, |
| 815 Handle<Name> name, | 733 Handle<Name> name, |
| 816 Handle<JSFunction> setter); | 734 Handle<JSFunction> setter); |
| 817 | 735 |
| 818 Handle<Code> CompileStoreInterceptor(Handle<JSObject> object, | 736 Handle<Code> CompileStoreInterceptor(Handle<JSObject> object, |
| 819 Handle<Name> name); | 737 Handle<Name> name); |
| 820 | 738 |
| 821 static Builtins::Name SlowBuiltin(Code::Kind kind) { | 739 static Builtins::Name SlowBuiltin(Code::Kind kind) { |
| 822 switch (kind) { | 740 switch (kind) { |
| 823 case Code::STORE_IC: return Builtins::kStoreIC_Slow; | 741 case Code::STORE_IC: return Builtins::kStoreIC_Slow; |
| 824 case Code::KEYED_STORE_IC: return Builtins::kKeyedStoreIC_Slow; | 742 case Code::KEYED_STORE_IC: return Builtins::kKeyedStoreIC_Slow; |
| 825 default: UNREACHABLE(); | 743 default: UNREACHABLE(); |
| 826 } | 744 } |
| 827 return Builtins::kStoreIC_Slow; | 745 return Builtins::kStoreIC_Slow; |
| 828 } | 746 } |
| 829 | 747 |
| 830 protected: | 748 protected: |
| 831 virtual Register HandlerFrontendHeader(Handle<Type> type, | 749 virtual Register HandlerFrontendHeader(Handle<HeapType> type, |
| 832 Register object_reg, | 750 Register object_reg, |
| 833 Handle<JSObject> holder, | 751 Handle<JSObject> holder, |
| 834 Handle<Name> name, | 752 Handle<Name> name, |
| 835 Label* miss); | 753 Label* miss); |
| 836 | 754 |
| 837 virtual void HandlerFrontendFooter(Handle<Name> name, Label* miss); | 755 virtual void HandlerFrontendFooter(Handle<Name> name, Label* miss); |
| 838 void GenerateRestoreName(MacroAssembler* masm, | 756 void GenerateRestoreName(MacroAssembler* masm, |
| 839 Label* label, | 757 Label* label, |
| 840 Handle<Name> name); | 758 Handle<Name> name); |
| 841 | 759 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 878 } | 796 } |
| 879 | 797 |
| 880 Register transition_map() { | 798 Register transition_map() { |
| 881 return registers()[3]; | 799 return registers()[3]; |
| 882 } | 800 } |
| 883 | 801 |
| 884 friend class BaseLoadStoreStubCompiler; | 802 friend class BaseLoadStoreStubCompiler; |
| 885 }; | 803 }; |
| 886 | 804 |
| 887 | 805 |
| 888 // Subset of FUNCTIONS_WITH_ID_LIST with custom constant/global call | |
| 889 // IC stubs. | |
| 890 #define CUSTOM_CALL_IC_GENERATORS(V) \ | |
| 891 V(ArrayPush) \ | |
| 892 V(ArrayPop) | |
| 893 | |
| 894 | |
| 895 class CallStubCompiler: public StubCompiler { | |
| 896 public: | |
| 897 CallStubCompiler(Isolate* isolate, | |
| 898 int argc, | |
| 899 Code::Kind kind, | |
| 900 ExtraICState extra_state, | |
| 901 InlineCacheHolderFlag cache_holder = OWN_MAP); | |
| 902 | |
| 903 Handle<Code> CompileCallField(Handle<JSObject> object, | |
| 904 Handle<JSObject> holder, | |
| 905 PropertyIndex index, | |
| 906 Handle<Name> name); | |
| 907 | |
| 908 // Patch the implicit receiver over the global object if the global object is | |
| 909 // the receiver. | |
| 910 void PatchImplicitReceiver(Handle<Object> object); | |
| 911 | |
| 912 // Returns the register containing the holder of |name|. | |
| 913 Register HandlerFrontendHeader(Handle<Object> object, | |
| 914 Handle<JSObject> holder, | |
| 915 Handle<Name> name, | |
| 916 CheckType check, | |
| 917 Label* miss); | |
| 918 void HandlerFrontendFooter(Label* miss); | |
| 919 | |
| 920 void GenerateJumpFunctionIgnoreReceiver(Handle<JSFunction> function); | |
| 921 void GenerateJumpFunction(Handle<Object> object, | |
| 922 Handle<JSFunction> function); | |
| 923 void GenerateJumpFunction(Handle<Object> object, | |
| 924 Register function, | |
| 925 Label* miss); | |
| 926 // Use to call |actual_closure|, a closure with the same shared function info | |
| 927 // as |function|. | |
| 928 void GenerateJumpFunction(Handle<Object> object, | |
| 929 Register actual_closure, | |
| 930 Handle<JSFunction> function); | |
| 931 | |
| 932 Handle<Code> CompileCallConstant(Handle<Object> object, | |
| 933 Handle<JSObject> holder, | |
| 934 Handle<Name> name, | |
| 935 CheckType check, | |
| 936 Handle<JSFunction> function); | |
| 937 | |
| 938 Handle<Code> CompileCallInterceptor(Handle<JSObject> object, | |
| 939 Handle<JSObject> holder, | |
| 940 Handle<Name> name); | |
| 941 | |
| 942 Handle<Code> CompileCallGlobal(Handle<JSObject> object, | |
| 943 Handle<GlobalObject> holder, | |
| 944 Handle<PropertyCell> cell, | |
| 945 Handle<JSFunction> function, | |
| 946 Handle<Name> name); | |
| 947 | |
| 948 static bool HasCustomCallGenerator(Handle<JSFunction> function); | |
| 949 | |
| 950 private: | |
| 951 // Compiles a custom call constant/global IC. For constant calls cell is | |
| 952 // NULL. Returns an empty handle if there is no custom call code for the | |
| 953 // given function. | |
| 954 Handle<Code> CompileCustomCall(Handle<Object> object, | |
| 955 Handle<JSObject> holder, | |
| 956 Handle<Cell> cell, | |
| 957 Handle<JSFunction> function, | |
| 958 Handle<String> name, | |
| 959 Code::StubType type); | |
| 960 | |
| 961 #define DECLARE_CALL_GENERATOR(name) \ | |
| 962 Handle<Code> Compile##name##Call(Handle<Object> object, \ | |
| 963 Handle<JSObject> holder, \ | |
| 964 Handle<Cell> cell, \ | |
| 965 Handle<JSFunction> function, \ | |
| 966 Handle<String> fname, \ | |
| 967 Code::StubType type); | |
| 968 CUSTOM_CALL_IC_GENERATORS(DECLARE_CALL_GENERATOR) | |
| 969 #undef DECLARE_CALL_GENERATOR | |
| 970 | |
| 971 Handle<Code> CompileFastApiCall(const CallOptimization& optimization, | |
| 972 Handle<Object> object, | |
| 973 Handle<JSObject> holder, | |
| 974 Handle<Cell> cell, | |
| 975 Handle<JSFunction> function, | |
| 976 Handle<String> name); | |
| 977 | |
| 978 Handle<Code> GetCode(Code::StubType type, Handle<Name> name); | |
| 979 Handle<Code> GetCode(Handle<JSFunction> function); | |
| 980 | |
| 981 const ParameterCount& arguments() { return arguments_; } | |
| 982 | |
| 983 void GenerateNameCheck(Handle<Name> name, Label* miss); | |
| 984 | |
| 985 // Generates code to load the function from the cell checking that | |
| 986 // it still contains the same function. | |
| 987 void GenerateLoadFunctionFromCell(Handle<Cell> cell, | |
| 988 Handle<JSFunction> function, | |
| 989 Label* miss); | |
| 990 | |
| 991 void GenerateFunctionCheck(Register function, Register scratch, Label* miss); | |
| 992 | |
| 993 // Generates a jump to CallIC miss stub. | |
| 994 void GenerateMissBranch(); | |
| 995 | |
| 996 const ParameterCount arguments_; | |
| 997 const Code::Kind kind_; | |
| 998 const InlineCacheHolderFlag cache_holder_; | |
| 999 }; | |
| 1000 | |
| 1001 | |
| 1002 // Holds information about possible function call optimizations. | 806 // Holds information about possible function call optimizations. |
| 1003 class CallOptimization BASE_EMBEDDED { | 807 class CallOptimization BASE_EMBEDDED { |
| 1004 public: | 808 public: |
| 1005 explicit CallOptimization(LookupResult* lookup); | 809 explicit CallOptimization(LookupResult* lookup); |
| 1006 | 810 |
| 1007 explicit CallOptimization(Handle<JSFunction> function); | 811 explicit CallOptimization(Handle<JSFunction> function); |
| 1008 | 812 |
| 1009 bool is_constant_call() const { | 813 bool is_constant_call() const { |
| 1010 return !constant_function_.is_null(); | 814 return !constant_function_.is_null(); |
| 1011 } | 815 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1022 Handle<FunctionTemplateInfo> expected_receiver_type() const { | 826 Handle<FunctionTemplateInfo> expected_receiver_type() const { |
| 1023 ASSERT(is_simple_api_call()); | 827 ASSERT(is_simple_api_call()); |
| 1024 return expected_receiver_type_; | 828 return expected_receiver_type_; |
| 1025 } | 829 } |
| 1026 | 830 |
| 1027 Handle<CallHandlerInfo> api_call_info() const { | 831 Handle<CallHandlerInfo> api_call_info() const { |
| 1028 ASSERT(is_simple_api_call()); | 832 ASSERT(is_simple_api_call()); |
| 1029 return api_call_info_; | 833 return api_call_info_; |
| 1030 } | 834 } |
| 1031 | 835 |
| 1032 // Returns the depth of the object having the expected type in the | 836 enum HolderLookup { |
| 1033 // prototype chain between the two arguments. | 837 kHolderNotFound, |
| 1034 int GetPrototypeDepthOfExpectedType(Handle<JSObject> object, | 838 kHolderIsReceiver, |
| 1035 Handle<JSObject> holder) const; | 839 kHolderFound |
| 840 }; |
| 841 Handle<JSObject> LookupHolderOfExpectedType( |
| 842 Handle<Map> receiver_map, |
| 843 HolderLookup* holder_lookup) const; |
| 1036 | 844 |
| 1037 bool IsCompatibleReceiver(Object* receiver) { | 845 // Check if the api holder is between the receiver and the holder. |
| 1038 ASSERT(is_simple_api_call()); | 846 bool IsCompatibleReceiver(Handle<Object> receiver, |
| 1039 if (expected_receiver_type_.is_null()) return true; | 847 Handle<JSObject> holder) const; |
| 1040 return expected_receiver_type_->IsTemplateFor(receiver); | |
| 1041 } | |
| 1042 | 848 |
| 1043 private: | 849 private: |
| 1044 void Initialize(Handle<JSFunction> function); | 850 void Initialize(Handle<JSFunction> function); |
| 1045 | 851 |
| 1046 // Determines whether the given function can be called using the | 852 // Determines whether the given function can be called using the |
| 1047 // fast api call builtin. | 853 // fast api call builtin. |
| 1048 void AnalyzePossibleApiFunction(Handle<JSFunction> function); | 854 void AnalyzePossibleApiFunction(Handle<JSFunction> function); |
| 1049 | 855 |
| 1050 Handle<JSFunction> constant_function_; | 856 Handle<JSFunction> constant_function_; |
| 1051 bool is_simple_api_call_; | 857 bool is_simple_api_call_; |
| 1052 Handle<FunctionTemplateInfo> expected_receiver_type_; | 858 Handle<FunctionTemplateInfo> expected_receiver_type_; |
| 1053 Handle<CallHandlerInfo> api_call_info_; | 859 Handle<CallHandlerInfo> api_call_info_; |
| 1054 }; | 860 }; |
| 1055 | 861 |
| 1056 | 862 |
| 1057 } } // namespace v8::internal | 863 } } // namespace v8::internal |
| 1058 | 864 |
| 1059 #endif // V8_STUB_CACHE_H_ | 865 #endif // V8_STUB_CACHE_H_ |
| OLD | NEW |