| 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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 primary->value = code; | 95 primary->value = code; |
| 96 primary->map = map; | 96 primary->map = map; |
| 97 isolate()->counters()->megamorphic_stub_cache_updates()->Increment(); | 97 isolate()->counters()->megamorphic_stub_cache_updates()->Increment(); |
| 98 return code; | 98 return code; |
| 99 } | 99 } |
| 100 | 100 |
| 101 | 101 |
| 102 Handle<Code> StubCache::FindIC(Handle<Name> name, | 102 Handle<Code> StubCache::FindIC(Handle<Name> name, |
| 103 Handle<Map> stub_holder, | 103 Handle<Map> stub_holder, |
| 104 Code::Kind kind, | 104 Code::Kind kind, |
| 105 Code::ExtraICState extra_state, | 105 ExtraICState extra_state, |
| 106 InlineCacheHolderFlag cache_holder) { | 106 InlineCacheHolderFlag cache_holder) { |
| 107 Code::Flags flags = Code::ComputeMonomorphicFlags( | 107 Code::Flags flags = Code::ComputeMonomorphicFlags( |
| 108 kind, extra_state, cache_holder); | 108 kind, extra_state, cache_holder); |
| 109 Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags), isolate_); | 109 Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags), isolate_); |
| 110 if (probe->IsCode()) return Handle<Code>::cast(probe); | 110 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| 111 return Handle<Code>::null(); | 111 return Handle<Code>::null(); |
| 112 } | 112 } |
| 113 | 113 |
| 114 | 114 |
| 115 Handle<Code> StubCache::FindHandler(Handle<Name> name, | 115 Handle<Code> StubCache::FindHandler(Handle<Name> name, |
| 116 Handle<Map> stub_holder, | 116 Handle<Map> stub_holder, |
| 117 Code::Kind kind, | 117 Code::Kind kind, |
| 118 InlineCacheHolderFlag cache_holder, | 118 InlineCacheHolderFlag cache_holder) { |
| 119 StrictModeFlag strict_mode) { | |
| 120 Code::ExtraICState extra_ic_state = Code::kNoExtraICState; | |
| 121 if (kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC) { | |
| 122 extra_ic_state = Code::ComputeExtraICState( | |
| 123 STANDARD_STORE, strict_mode); | |
| 124 } | |
| 125 Code::Flags flags = Code::ComputeMonomorphicFlags( | 119 Code::Flags flags = Code::ComputeMonomorphicFlags( |
| 126 Code::HANDLER, extra_ic_state, cache_holder, Code::NORMAL, kind); | 120 Code::HANDLER, kNoExtraICState, cache_holder, Code::NORMAL, kind); |
| 127 | 121 |
| 128 Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags), isolate_); | 122 Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags), isolate_); |
| 129 if (probe->IsCode()) return Handle<Code>::cast(probe); | 123 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| 130 return Handle<Code>::null(); | 124 return Handle<Code>::null(); |
| 131 } | 125 } |
| 132 | 126 |
| 133 | 127 |
| 134 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<Name> name, | 128 Handle<Code> StubCache::ComputeMonomorphicIC( |
| 135 Handle<Type> type, | 129 Handle<Name> name, |
| 136 Handle<Code> handler, | 130 Handle<Type> type, |
| 137 StrictModeFlag strict_mode) { | 131 Handle<Code> handler, |
| 132 ExtraICState extra_ic_state) { |
| 138 Code::Kind kind = handler->handler_kind(); | 133 Code::Kind kind = handler->handler_kind(); |
| 139 InlineCacheHolderFlag flag = IC::GetCodeCacheFlag(*type); | 134 InlineCacheHolderFlag flag = IC::GetCodeCacheFlag(*type); |
| 140 | 135 |
| 141 Handle<Map> stub_holder; | 136 Handle<Map> stub_holder; |
| 142 Handle<Code> ic; | 137 Handle<Code> ic; |
| 143 // There are multiple string maps that all use the same prototype. That | 138 // There are multiple string maps that all use the same prototype. That |
| 144 // prototype cannot hold multiple handlers, one for each of the string maps, | 139 // prototype cannot hold multiple handlers, one for each of the string maps, |
| 145 // for a single name. Hence, turn off caching of the IC. | 140 // for a single name. Hence, turn off caching of the IC. |
| 146 bool can_be_cached = !type->Is(Type::String()); | 141 bool can_be_cached = !type->Is(Type::String()); |
| 147 if (can_be_cached) { | 142 if (can_be_cached) { |
| 148 stub_holder = IC::GetCodeCacheHolder(flag, *type, isolate()); | 143 stub_holder = IC::GetCodeCacheHolder(flag, *type, isolate()); |
| 149 ic = FindIC(name, stub_holder, kind, strict_mode, flag); | 144 ic = FindIC(name, stub_holder, kind, extra_ic_state, flag); |
| 150 if (!ic.is_null()) return ic; | 145 if (!ic.is_null()) return ic; |
| 151 } | 146 } |
| 152 | 147 |
| 153 if (kind == Code::LOAD_IC) { | 148 if (kind == Code::LOAD_IC) { |
| 154 LoadStubCompiler ic_compiler(isolate(), flag); | 149 LoadStubCompiler ic_compiler(isolate(), flag); |
| 155 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); | 150 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); |
| 156 } else if (kind == Code::KEYED_LOAD_IC) { | 151 } else if (kind == Code::KEYED_LOAD_IC) { |
| 157 KeyedLoadStubCompiler ic_compiler(isolate(), flag); | 152 KeyedLoadStubCompiler ic_compiler(isolate(), flag); |
| 158 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); | 153 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); |
| 159 } else if (kind == Code::STORE_IC) { | 154 } else if (kind == Code::STORE_IC) { |
| 155 StrictModeFlag strict_mode = StoreIC::GetStrictMode(extra_ic_state); |
| 160 StoreStubCompiler ic_compiler(isolate(), strict_mode); | 156 StoreStubCompiler ic_compiler(isolate(), strict_mode); |
| 161 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); | 157 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); |
| 162 } else { | 158 } else { |
| 163 ASSERT(kind == Code::KEYED_STORE_IC); | 159 ASSERT(kind == Code::KEYED_STORE_IC); |
| 160 StrictModeFlag strict_mode = StoreIC::GetStrictMode(extra_ic_state); |
| 164 KeyedStoreStubCompiler ic_compiler(isolate(), strict_mode, STANDARD_STORE); | 161 KeyedStoreStubCompiler ic_compiler(isolate(), strict_mode, STANDARD_STORE); |
| 165 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); | 162 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); |
| 166 } | 163 } |
| 167 | 164 |
| 168 if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic); | 165 if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic); |
| 169 return ic; | 166 return ic; |
| 170 } | 167 } |
| 171 | 168 |
| 172 | 169 |
| 173 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name, | 170 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name, |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 | 214 |
| 218 Map::UpdateCodeCache(receiver_map, name, code); | 215 Map::UpdateCodeCache(receiver_map, name, code); |
| 219 return code; | 216 return code; |
| 220 } | 217 } |
| 221 | 218 |
| 222 | 219 |
| 223 Handle<Code> StubCache::ComputeKeyedStoreElement( | 220 Handle<Code> StubCache::ComputeKeyedStoreElement( |
| 224 Handle<Map> receiver_map, | 221 Handle<Map> receiver_map, |
| 225 StrictModeFlag strict_mode, | 222 StrictModeFlag strict_mode, |
| 226 KeyedAccessStoreMode store_mode) { | 223 KeyedAccessStoreMode store_mode) { |
| 227 Code::ExtraICState extra_state = | 224 ExtraICState extra_state = |
| 228 Code::ComputeExtraICState(store_mode, strict_mode); | 225 KeyedStoreIC::ComputeExtraICState(strict_mode, store_mode); |
| 229 Code::Flags flags = Code::ComputeMonomorphicFlags( | 226 Code::Flags flags = Code::ComputeMonomorphicFlags( |
| 230 Code::KEYED_STORE_IC, extra_state); | 227 Code::KEYED_STORE_IC, extra_state); |
| 231 | 228 |
| 232 ASSERT(store_mode == STANDARD_STORE || | 229 ASSERT(store_mode == STANDARD_STORE || |
| 233 store_mode == STORE_AND_GROW_NO_TRANSITION || | 230 store_mode == STORE_AND_GROW_NO_TRANSITION || |
| 234 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || | 231 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || |
| 235 store_mode == STORE_NO_TRANSITION_HANDLE_COW); | 232 store_mode == STORE_NO_TRANSITION_HANDLE_COW); |
| 236 | 233 |
| 237 Handle<String> name = | 234 Handle<String> name = |
| 238 isolate()->factory()->KeyedStoreElementMonomorphic_string(); | 235 isolate()->factory()->KeyedStoreElementMonomorphic_string(); |
| 239 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); | 236 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); |
| 240 if (probe->IsCode()) return Handle<Code>::cast(probe); | 237 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| 241 | 238 |
| 242 KeyedStoreStubCompiler compiler(isolate(), strict_mode, store_mode); | 239 KeyedStoreStubCompiler compiler(isolate(), strict_mode, store_mode); |
| 243 Handle<Code> code = compiler.CompileStoreElement(receiver_map); | 240 Handle<Code> code = compiler.CompileStoreElement(receiver_map); |
| 244 | 241 |
| 245 Map::UpdateCodeCache(receiver_map, name, code); | 242 Map::UpdateCodeCache(receiver_map, name, code); |
| 246 ASSERT(Code::GetKeyedAccessStoreMode(code->extra_ic_state()) == store_mode); | 243 ASSERT(KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state()) |
| 244 == store_mode); |
| 247 return code; | 245 return code; |
| 248 } | 246 } |
| 249 | 247 |
| 250 | 248 |
| 251 #define CALL_LOGGER_TAG(kind, type) \ | 249 #define CALL_LOGGER_TAG(kind, type) \ |
| 252 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) | 250 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) |
| 253 | 251 |
| 254 Handle<Code> StubCache::ComputeCallConstant(int argc, | 252 Handle<Code> StubCache::ComputeCallConstant(int argc, |
| 255 Code::Kind kind, | 253 Code::Kind kind, |
| 256 Code::ExtraICState extra_state, | 254 ExtraICState extra_state, |
| 257 Handle<Name> name, | 255 Handle<Name> name, |
| 258 Handle<Object> object, | 256 Handle<Object> object, |
| 259 Handle<JSObject> holder, | 257 Handle<JSObject> holder, |
| 260 Handle<JSFunction> function) { | 258 Handle<JSFunction> function) { |
| 261 // Compute the check type and the map. | 259 // Compute the check type and the map. |
| 262 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object); | 260 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object); |
| 263 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder( | 261 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder( |
| 264 isolate_, *object, cache_holder)); | 262 isolate_, *object, cache_holder)); |
| 265 | 263 |
| 266 // Compute check type based on receiver/holder. | 264 // Compute check type based on receiver/holder. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 | 298 |
| 301 if (CallStubCompiler::CanBeCached(function)) { | 299 if (CallStubCompiler::CanBeCached(function)) { |
| 302 HeapObject::UpdateMapCodeCache(stub_holder, name, code); | 300 HeapObject::UpdateMapCodeCache(stub_holder, name, code); |
| 303 } | 301 } |
| 304 return code; | 302 return code; |
| 305 } | 303 } |
| 306 | 304 |
| 307 | 305 |
| 308 Handle<Code> StubCache::ComputeCallField(int argc, | 306 Handle<Code> StubCache::ComputeCallField(int argc, |
| 309 Code::Kind kind, | 307 Code::Kind kind, |
| 310 Code::ExtraICState extra_state, | 308 ExtraICState extra_state, |
| 311 Handle<Name> name, | 309 Handle<Name> name, |
| 312 Handle<Object> object, | 310 Handle<Object> object, |
| 313 Handle<JSObject> holder, | 311 Handle<JSObject> holder, |
| 314 PropertyIndex index) { | 312 PropertyIndex index) { |
| 315 // Compute the check type and the map. | 313 // Compute the check type and the map. |
| 316 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object); | 314 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object); |
| 317 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder( | 315 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder( |
| 318 isolate_, *object, cache_holder)); | 316 isolate_, *object, cache_holder)); |
| 319 | 317 |
| 320 // TODO(1233596): We cannot do receiver map check for non-JS objects | 318 // TODO(1233596): We cannot do receiver map check for non-JS objects |
| (...skipping 18 matching lines...) Expand all Loading... |
| 339 PROFILE(isolate_, | 337 PROFILE(isolate_, |
| 340 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); | 338 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); |
| 341 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); | 339 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); |
| 342 HeapObject::UpdateMapCodeCache(stub_holder, name, code); | 340 HeapObject::UpdateMapCodeCache(stub_holder, name, code); |
| 343 return code; | 341 return code; |
| 344 } | 342 } |
| 345 | 343 |
| 346 | 344 |
| 347 Handle<Code> StubCache::ComputeCallInterceptor(int argc, | 345 Handle<Code> StubCache::ComputeCallInterceptor(int argc, |
| 348 Code::Kind kind, | 346 Code::Kind kind, |
| 349 Code::ExtraICState extra_state, | 347 ExtraICState extra_state, |
| 350 Handle<Name> name, | 348 Handle<Name> name, |
| 351 Handle<Object> object, | 349 Handle<Object> object, |
| 352 Handle<JSObject> holder) { | 350 Handle<JSObject> holder) { |
| 353 // Compute the check type and the map. | 351 // Compute the check type and the map. |
| 354 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object); | 352 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object); |
| 355 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder( | 353 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder( |
| 356 isolate_, *object, cache_holder)); | 354 isolate_, *object, cache_holder)); |
| 357 | 355 |
| 358 // TODO(1233596): We cannot do receiver map check for non-JS objects | 356 // TODO(1233596): We cannot do receiver map check for non-JS objects |
| 359 // because they may be represented as immediates without a | 357 // because they may be represented as immediates without a |
| (...skipping 17 matching lines...) Expand all Loading... |
| 377 PROFILE(isolate(), | 375 PROFILE(isolate(), |
| 378 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); | 376 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); |
| 379 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); | 377 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); |
| 380 HeapObject::UpdateMapCodeCache(stub_holder, name, code); | 378 HeapObject::UpdateMapCodeCache(stub_holder, name, code); |
| 381 return code; | 379 return code; |
| 382 } | 380 } |
| 383 | 381 |
| 384 | 382 |
| 385 Handle<Code> StubCache::ComputeCallGlobal(int argc, | 383 Handle<Code> StubCache::ComputeCallGlobal(int argc, |
| 386 Code::Kind kind, | 384 Code::Kind kind, |
| 387 Code::ExtraICState extra_state, | 385 ExtraICState extra_state, |
| 388 Handle<Name> name, | 386 Handle<Name> name, |
| 389 Handle<JSObject> receiver, | 387 Handle<JSObject> receiver, |
| 390 Handle<GlobalObject> holder, | 388 Handle<GlobalObject> holder, |
| 391 Handle<PropertyCell> cell, | 389 Handle<PropertyCell> cell, |
| 392 Handle<JSFunction> function) { | 390 Handle<JSFunction> function) { |
| 393 Code::Flags flags = Code::ComputeMonomorphicFlags( | 391 Code::Flags flags = Code::ComputeMonomorphicFlags( |
| 394 kind, extra_state, OWN_MAP, Code::NORMAL, argc); | 392 kind, extra_state, OWN_MAP, Code::NORMAL, argc); |
| 395 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), | 393 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), |
| 396 isolate_); | 394 isolate_); |
| 397 if (probe->IsCode()) return Handle<Code>::cast(probe); | 395 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 415 UnseededNumberDictionary::Set(isolate->factory()->non_monomorphic_cache(), | 413 UnseededNumberDictionary::Set(isolate->factory()->non_monomorphic_cache(), |
| 416 code->flags(), | 414 code->flags(), |
| 417 code); | 415 code); |
| 418 isolate->heap()->public_set_non_monomorphic_cache(*dictionary); | 416 isolate->heap()->public_set_non_monomorphic_cache(*dictionary); |
| 419 } | 417 } |
| 420 | 418 |
| 421 | 419 |
| 422 Code* StubCache::FindCallInitialize(int argc, | 420 Code* StubCache::FindCallInitialize(int argc, |
| 423 RelocInfo::Mode mode, | 421 RelocInfo::Mode mode, |
| 424 Code::Kind kind) { | 422 Code::Kind kind) { |
| 425 Code::ExtraICState extra_state = | 423 ExtraICState extra_state = |
| 426 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) | | 424 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) | |
| 427 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT); | 425 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT |
| 426 ? CONTEXTUAL : NOT_CONTEXTUAL); |
| 428 Code::Flags flags = | 427 Code::Flags flags = |
| 429 Code::ComputeFlags(kind, UNINITIALIZED, extra_state, Code::NORMAL, argc); | 428 Code::ComputeFlags(kind, UNINITIALIZED, extra_state, Code::NORMAL, argc); |
| 430 UnseededNumberDictionary* dictionary = | 429 UnseededNumberDictionary* dictionary = |
| 431 isolate()->heap()->non_monomorphic_cache(); | 430 isolate()->heap()->non_monomorphic_cache(); |
| 432 int entry = dictionary->FindEntry(isolate(), flags); | 431 int entry = dictionary->FindEntry(isolate(), flags); |
| 433 ASSERT(entry != -1); | 432 ASSERT(entry != -1); |
| 434 Object* code = dictionary->ValueAt(entry); | 433 Object* code = dictionary->ValueAt(entry); |
| 435 // This might be called during the marking phase of the collector | 434 // This might be called during the marking phase of the collector |
| 436 // hence the unchecked cast. | 435 // hence the unchecked cast. |
| 437 return reinterpret_cast<Code*>(code); | 436 return reinterpret_cast<Code*>(code); |
| 438 } | 437 } |
| 439 | 438 |
| 440 | 439 |
| 441 Handle<Code> StubCache::ComputeCallInitialize(int argc, | 440 Handle<Code> StubCache::ComputeCallInitialize(int argc, |
| 442 RelocInfo::Mode mode, | 441 RelocInfo::Mode mode, |
| 443 Code::Kind kind) { | 442 Code::Kind kind) { |
| 444 Code::ExtraICState extra_state = | 443 ExtraICState extra_state = |
| 445 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) | | 444 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) | |
| 446 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT); | 445 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT |
| 446 ? CONTEXTUAL : NOT_CONTEXTUAL); |
| 447 Code::Flags flags = | 447 Code::Flags flags = |
| 448 Code::ComputeFlags(kind, UNINITIALIZED, extra_state, Code::NORMAL, argc); | 448 Code::ComputeFlags(kind, UNINITIALIZED, extra_state, Code::NORMAL, argc); |
| 449 Handle<UnseededNumberDictionary> cache = | 449 Handle<UnseededNumberDictionary> cache = |
| 450 isolate_->factory()->non_monomorphic_cache(); | 450 isolate_->factory()->non_monomorphic_cache(); |
| 451 int entry = cache->FindEntry(isolate_, flags); | 451 int entry = cache->FindEntry(isolate_, flags); |
| 452 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); | 452 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); |
| 453 | 453 |
| 454 StubCompiler compiler(isolate_); | 454 StubCompiler compiler(isolate_); |
| 455 Handle<Code> code = compiler.CompileCallInitialize(flags); | 455 Handle<Code> code = compiler.CompileCallInitialize(flags); |
| 456 FillCache(isolate_, code); | 456 FillCache(isolate_, code); |
| 457 return code; | 457 return code; |
| 458 } | 458 } |
| 459 | 459 |
| 460 | 460 |
| 461 Handle<Code> StubCache::ComputeCallInitialize(int argc, RelocInfo::Mode mode) { | 461 Handle<Code> StubCache::ComputeCallInitialize(int argc, RelocInfo::Mode mode) { |
| 462 return ComputeCallInitialize(argc, mode, Code::CALL_IC); | 462 return ComputeCallInitialize(argc, mode, Code::CALL_IC); |
| 463 } | 463 } |
| 464 | 464 |
| 465 | 465 |
| 466 Handle<Code> StubCache::ComputeKeyedCallInitialize(int argc) { | 466 Handle<Code> StubCache::ComputeKeyedCallInitialize(int argc) { |
| 467 return ComputeCallInitialize(argc, RelocInfo::CODE_TARGET, | 467 return ComputeCallInitialize(argc, RelocInfo::CODE_TARGET, |
| 468 Code::KEYED_CALL_IC); | 468 Code::KEYED_CALL_IC); |
| 469 } | 469 } |
| 470 | 470 |
| 471 | 471 |
| 472 Handle<Code> StubCache::ComputeCallPreMonomorphic( | 472 Handle<Code> StubCache::ComputeCallPreMonomorphic( |
| 473 int argc, | 473 int argc, |
| 474 Code::Kind kind, | 474 Code::Kind kind, |
| 475 Code::ExtraICState extra_state) { | 475 ExtraICState extra_state) { |
| 476 Code::Flags flags = | 476 Code::Flags flags = |
| 477 Code::ComputeFlags(kind, PREMONOMORPHIC, extra_state, Code::NORMAL, argc); | 477 Code::ComputeFlags(kind, PREMONOMORPHIC, extra_state, Code::NORMAL, argc); |
| 478 Handle<UnseededNumberDictionary> cache = | 478 Handle<UnseededNumberDictionary> cache = |
| 479 isolate_->factory()->non_monomorphic_cache(); | 479 isolate_->factory()->non_monomorphic_cache(); |
| 480 int entry = cache->FindEntry(isolate_, flags); | 480 int entry = cache->FindEntry(isolate_, flags); |
| 481 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); | 481 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); |
| 482 | 482 |
| 483 StubCompiler compiler(isolate_); | 483 StubCompiler compiler(isolate_); |
| 484 Handle<Code> code = compiler.CompileCallPreMonomorphic(flags); | 484 Handle<Code> code = compiler.CompileCallPreMonomorphic(flags); |
| 485 FillCache(isolate_, code); | 485 FillCache(isolate_, code); |
| 486 return code; | 486 return code; |
| 487 } | 487 } |
| 488 | 488 |
| 489 | 489 |
| 490 Handle<Code> StubCache::ComputeCallNormal(int argc, | 490 Handle<Code> StubCache::ComputeCallNormal(int argc, |
| 491 Code::Kind kind, | 491 Code::Kind kind, |
| 492 Code::ExtraICState extra_state) { | 492 ExtraICState extra_state) { |
| 493 Code::Flags flags = | 493 Code::Flags flags = |
| 494 Code::ComputeFlags(kind, MONOMORPHIC, extra_state, Code::NORMAL, argc); | 494 Code::ComputeFlags(kind, MONOMORPHIC, extra_state, Code::NORMAL, argc); |
| 495 Handle<UnseededNumberDictionary> cache = | 495 Handle<UnseededNumberDictionary> cache = |
| 496 isolate_->factory()->non_monomorphic_cache(); | 496 isolate_->factory()->non_monomorphic_cache(); |
| 497 int entry = cache->FindEntry(isolate_, flags); | 497 int entry = cache->FindEntry(isolate_, flags); |
| 498 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); | 498 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); |
| 499 | 499 |
| 500 StubCompiler compiler(isolate_); | 500 StubCompiler compiler(isolate_); |
| 501 Handle<Code> code = compiler.CompileCallNormal(flags); | 501 Handle<Code> code = compiler.CompileCallNormal(flags); |
| 502 FillCache(isolate_, code); | 502 FillCache(isolate_, code); |
| 503 return code; | 503 return code; |
| 504 } | 504 } |
| 505 | 505 |
| 506 | 506 |
| 507 Handle<Code> StubCache::ComputeCallArguments(int argc) { | 507 Handle<Code> StubCache::ComputeCallArguments(int argc) { |
| 508 Code::Flags flags = | 508 Code::Flags flags = |
| 509 Code::ComputeFlags(Code::KEYED_CALL_IC, MEGAMORPHIC, | 509 Code::ComputeFlags(Code::KEYED_CALL_IC, MEGAMORPHIC, |
| 510 Code::kNoExtraICState, Code::NORMAL, argc); | 510 kNoExtraICState, Code::NORMAL, argc); |
| 511 Handle<UnseededNumberDictionary> cache = | 511 Handle<UnseededNumberDictionary> cache = |
| 512 isolate_->factory()->non_monomorphic_cache(); | 512 isolate_->factory()->non_monomorphic_cache(); |
| 513 int entry = cache->FindEntry(isolate_, flags); | 513 int entry = cache->FindEntry(isolate_, flags); |
| 514 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); | 514 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); |
| 515 | 515 |
| 516 StubCompiler compiler(isolate_); | 516 StubCompiler compiler(isolate_); |
| 517 Handle<Code> code = compiler.CompileCallArguments(flags); | 517 Handle<Code> code = compiler.CompileCallArguments(flags); |
| 518 FillCache(isolate_, code); | 518 FillCache(isolate_, code); |
| 519 return code; | 519 return code; |
| 520 } | 520 } |
| 521 | 521 |
| 522 | 522 |
| 523 Handle<Code> StubCache::ComputeCallMegamorphic( | 523 Handle<Code> StubCache::ComputeCallMegamorphic( |
| 524 int argc, | 524 int argc, |
| 525 Code::Kind kind, | 525 Code::Kind kind, |
| 526 Code::ExtraICState extra_state) { | 526 ExtraICState extra_state) { |
| 527 Code::Flags flags = | 527 Code::Flags flags = |
| 528 Code::ComputeFlags(kind, MEGAMORPHIC, extra_state, | 528 Code::ComputeFlags(kind, MEGAMORPHIC, extra_state, |
| 529 Code::NORMAL, argc); | 529 Code::NORMAL, argc); |
| 530 Handle<UnseededNumberDictionary> cache = | 530 Handle<UnseededNumberDictionary> cache = |
| 531 isolate_->factory()->non_monomorphic_cache(); | 531 isolate_->factory()->non_monomorphic_cache(); |
| 532 int entry = cache->FindEntry(isolate_, flags); | 532 int entry = cache->FindEntry(isolate_, flags); |
| 533 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); | 533 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); |
| 534 | 534 |
| 535 StubCompiler compiler(isolate_); | 535 StubCompiler compiler(isolate_); |
| 536 Handle<Code> code = compiler.CompileCallMegamorphic(flags); | 536 Handle<Code> code = compiler.CompileCallMegamorphic(flags); |
| 537 FillCache(isolate_, code); | 537 FillCache(isolate_, code); |
| 538 return code; | 538 return code; |
| 539 } | 539 } |
| 540 | 540 |
| 541 | 541 |
| 542 Handle<Code> StubCache::ComputeCallMiss(int argc, | 542 Handle<Code> StubCache::ComputeCallMiss(int argc, |
| 543 Code::Kind kind, | 543 Code::Kind kind, |
| 544 Code::ExtraICState extra_state) { | 544 ExtraICState extra_state) { |
| 545 // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs | 545 // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs |
| 546 // and monomorphic stubs are not mixed up together in the stub cache. | 546 // and monomorphic stubs are not mixed up together in the stub cache. |
| 547 Code::Flags flags = | 547 Code::Flags flags = |
| 548 Code::ComputeFlags(kind, MONOMORPHIC_PROTOTYPE_FAILURE, extra_state, | 548 Code::ComputeFlags(kind, MONOMORPHIC_PROTOTYPE_FAILURE, extra_state, |
| 549 Code::NORMAL, argc, OWN_MAP); | 549 Code::NORMAL, argc, OWN_MAP); |
| 550 Handle<UnseededNumberDictionary> cache = | 550 Handle<UnseededNumberDictionary> cache = |
| 551 isolate_->factory()->non_monomorphic_cache(); | 551 isolate_->factory()->non_monomorphic_cache(); |
| 552 int entry = cache->FindEntry(isolate_, flags); | 552 int entry = cache->FindEntry(isolate_, flags); |
| 553 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); | 553 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); |
| 554 | 554 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 Handle<Code> code = compiler.CompilePolymorphicIC( | 598 Handle<Code> code = compiler.CompilePolymorphicIC( |
| 599 &types, &handlers, factory()->empty_string(), Code::NORMAL, ELEMENT); | 599 &types, &handlers, factory()->empty_string(), Code::NORMAL, ELEMENT); |
| 600 | 600 |
| 601 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment(); | 601 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment(); |
| 602 | 602 |
| 603 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); | 603 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); |
| 604 return code; | 604 return code; |
| 605 } | 605 } |
| 606 | 606 |
| 607 | 607 |
| 608 Handle<Code> StubCache::ComputePolymorphicIC(TypeHandleList* types, | 608 Handle<Code> StubCache::ComputePolymorphicIC( |
| 609 CodeHandleList* handlers, | 609 TypeHandleList* types, |
| 610 int number_of_valid_types, | 610 CodeHandleList* handlers, |
| 611 Handle<Name> name, | 611 int number_of_valid_types, |
| 612 StrictModeFlag strict_mode) { | 612 Handle<Name> name, |
| 613 ExtraICState extra_ic_state) { |
| 614 |
| 613 Handle<Code> handler = handlers->at(0); | 615 Handle<Code> handler = handlers->at(0); |
| 614 Code::Kind kind = handler->handler_kind(); | 616 Code::Kind kind = handler->handler_kind(); |
| 615 Code::StubType type = number_of_valid_types == 1 ? handler->type() | 617 Code::StubType type = number_of_valid_types == 1 ? handler->type() |
| 616 : Code::NORMAL; | 618 : Code::NORMAL; |
| 617 if (kind == Code::LOAD_IC) { | 619 if (kind == Code::LOAD_IC) { |
| 618 LoadStubCompiler ic_compiler(isolate_); | 620 LoadStubCompiler ic_compiler(isolate_); |
| 619 return ic_compiler.CompilePolymorphicIC( | 621 return ic_compiler.CompilePolymorphicIC( |
| 620 types, handlers, name, type, PROPERTY); | 622 types, handlers, name, type, PROPERTY); |
| 621 } else { | 623 } else { |
| 622 ASSERT(kind == Code::STORE_IC); | 624 ASSERT(kind == Code::STORE_IC); |
| 625 StrictModeFlag strict_mode = StoreIC::GetStrictMode(extra_ic_state); |
| 623 StoreStubCompiler ic_compiler(isolate_, strict_mode); | 626 StoreStubCompiler ic_compiler(isolate_, strict_mode); |
| 624 return ic_compiler.CompilePolymorphicIC( | 627 return ic_compiler.CompilePolymorphicIC( |
| 625 types, handlers, name, type, PROPERTY); | 628 types, handlers, name, type, PROPERTY); |
| 626 } | 629 } |
| 627 } | 630 } |
| 628 | 631 |
| 629 | 632 |
| 630 Handle<Code> StubCache::ComputeStoreElementPolymorphic( | 633 Handle<Code> StubCache::ComputeStoreElementPolymorphic( |
| 631 MapHandleList* receiver_maps, | 634 MapHandleList* receiver_maps, |
| 632 KeyedAccessStoreMode store_mode, | 635 KeyedAccessStoreMode store_mode, |
| 633 StrictModeFlag strict_mode) { | 636 StrictModeFlag strict_mode) { |
| 634 ASSERT(store_mode == STANDARD_STORE || | 637 ASSERT(store_mode == STANDARD_STORE || |
| 635 store_mode == STORE_AND_GROW_NO_TRANSITION || | 638 store_mode == STORE_AND_GROW_NO_TRANSITION || |
| 636 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || | 639 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || |
| 637 store_mode == STORE_NO_TRANSITION_HANDLE_COW); | 640 store_mode == STORE_NO_TRANSITION_HANDLE_COW); |
| 638 Handle<PolymorphicCodeCache> cache = | 641 Handle<PolymorphicCodeCache> cache = |
| 639 isolate_->factory()->polymorphic_code_cache(); | 642 isolate_->factory()->polymorphic_code_cache(); |
| 640 Code::ExtraICState extra_state = Code::ComputeExtraICState(store_mode, | 643 ExtraICState extra_state = KeyedStoreIC::ComputeExtraICState( |
| 641 strict_mode); | 644 strict_mode, store_mode); |
| 642 Code::Flags flags = | 645 Code::Flags flags = |
| 643 Code::ComputeFlags(Code::KEYED_STORE_IC, POLYMORPHIC, extra_state); | 646 Code::ComputeFlags(Code::KEYED_STORE_IC, POLYMORPHIC, extra_state); |
| 644 Handle<Object> probe = cache->Lookup(receiver_maps, flags); | 647 Handle<Object> probe = cache->Lookup(receiver_maps, flags); |
| 645 if (probe->IsCode()) return Handle<Code>::cast(probe); | 648 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| 646 | 649 |
| 647 KeyedStoreStubCompiler compiler(isolate_, strict_mode, store_mode); | 650 KeyedStoreStubCompiler compiler(isolate_, strict_mode, store_mode); |
| 648 Handle<Code> code = compiler.CompileStoreElementPolymorphic(receiver_maps); | 651 Handle<Code> code = compiler.CompileStoreElementPolymorphic(receiver_maps); |
| 649 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); | 652 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); |
| 650 return code; | 653 return code; |
| 651 } | 654 } |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 914 RETURN_IF_EMPTY_HANDLE(isolate, result); | 917 RETURN_IF_EMPTY_HANDLE(isolate, result); |
| 915 // This is call IC. In this case, we simply return the undefined result which | 918 // This is call IC. In this case, we simply return the undefined result which |
| 916 // will lead to an exception when trying to invoke the result as a | 919 // will lead to an exception when trying to invoke the result as a |
| 917 // function. | 920 // function. |
| 918 return *result; | 921 return *result; |
| 919 } | 922 } |
| 920 | 923 |
| 921 | 924 |
| 922 RUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty) { | 925 RUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty) { |
| 923 HandleScope scope(isolate); | 926 HandleScope scope(isolate); |
| 924 ASSERT(args.length() == 4); | 927 ASSERT(args.length() == 3); |
| 925 Handle<JSObject> recv(JSObject::cast(args[0])); | 928 StoreIC ic(IC::NO_EXTRA_FRAME, isolate); |
| 926 Handle<Name> name(Name::cast(args[1])); | 929 Handle<JSObject> receiver = args.at<JSObject>(0); |
| 927 Handle<Object> value(args[2], isolate); | 930 Handle<Name> name = args.at<Name>(1); |
| 928 ASSERT(args.smi_at(3) == kStrictMode || args.smi_at(3) == kNonStrictMode); | 931 Handle<Object> value = args.at<Object>(2); |
| 929 StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(3)); | 932 ASSERT(receiver->HasNamedInterceptor()); |
| 930 ASSERT(recv->HasNamedInterceptor()); | |
| 931 PropertyAttributes attr = NONE; | 933 PropertyAttributes attr = NONE; |
| 932 Handle<Object> result = JSObject::SetPropertyWithInterceptor( | 934 Handle<Object> result = JSObject::SetPropertyWithInterceptor( |
| 933 recv, name, value, attr, strict_mode); | 935 receiver, name, value, attr, ic.strict_mode()); |
| 934 RETURN_IF_EMPTY_HANDLE(isolate, result); | 936 RETURN_IF_EMPTY_HANDLE(isolate, result); |
| 935 return *result; | 937 return *result; |
| 936 } | 938 } |
| 937 | 939 |
| 938 | 940 |
| 939 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor) { | 941 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor) { |
| 940 JSObject* receiver = JSObject::cast(args[0]); | 942 JSObject* receiver = JSObject::cast(args[0]); |
| 941 ASSERT(args.smi_at(1) >= 0); | 943 ASSERT(args.smi_at(1) >= 0); |
| 942 uint32_t index = args.smi_at(1); | 944 uint32_t index = args.smi_at(1); |
| 943 return receiver->GetElementWithInterceptor(receiver, index); | 945 return receiver->GetElementWithInterceptor(receiver, index); |
| 944 } | 946 } |
| 945 | 947 |
| 946 | 948 |
| 947 Handle<Code> StubCompiler::CompileCallInitialize(Code::Flags flags) { | 949 Handle<Code> StubCompiler::CompileCallInitialize(Code::Flags flags) { |
| 948 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 950 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
| 949 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 951 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
| 950 Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); | 952 ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); |
| 951 if (kind == Code::CALL_IC) { | 953 if (kind == Code::CALL_IC) { |
| 952 CallIC::GenerateInitialize(masm(), argc, extra_state); | 954 CallIC::GenerateInitialize(masm(), argc, extra_state); |
| 953 } else { | 955 } else { |
| 954 KeyedCallIC::GenerateInitialize(masm(), argc); | 956 KeyedCallIC::GenerateInitialize(masm(), argc); |
| 955 } | 957 } |
| 956 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallInitialize"); | 958 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallInitialize"); |
| 957 isolate()->counters()->call_initialize_stubs()->Increment(); | 959 isolate()->counters()->call_initialize_stubs()->Increment(); |
| 958 PROFILE(isolate(), | 960 PROFILE(isolate(), |
| 959 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_INITIALIZE_TAG), | 961 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_INITIALIZE_TAG), |
| 960 *code, code->arguments_count())); | 962 *code, code->arguments_count())); |
| 961 GDBJIT(AddCode(GDBJITInterface::CALL_INITIALIZE, *code)); | 963 GDBJIT(AddCode(GDBJITInterface::CALL_INITIALIZE, *code)); |
| 962 return code; | 964 return code; |
| 963 } | 965 } |
| 964 | 966 |
| 965 | 967 |
| 966 Handle<Code> StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) { | 968 Handle<Code> StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) { |
| 967 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 969 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
| 968 // The code of the PreMonomorphic stub is the same as the code | 970 // The code of the PreMonomorphic stub is the same as the code |
| 969 // of the Initialized stub. They just differ on the code object flags. | 971 // of the Initialized stub. They just differ on the code object flags. |
| 970 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 972 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
| 971 Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); | 973 ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); |
| 972 if (kind == Code::CALL_IC) { | 974 if (kind == Code::CALL_IC) { |
| 973 CallIC::GenerateInitialize(masm(), argc, extra_state); | 975 CallIC::GenerateInitialize(masm(), argc, extra_state); |
| 974 } else { | 976 } else { |
| 975 KeyedCallIC::GenerateInitialize(masm(), argc); | 977 KeyedCallIC::GenerateInitialize(masm(), argc); |
| 976 } | 978 } |
| 977 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallPreMonomorphic"); | 979 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallPreMonomorphic"); |
| 978 isolate()->counters()->call_premonomorphic_stubs()->Increment(); | 980 isolate()->counters()->call_premonomorphic_stubs()->Increment(); |
| 979 PROFILE(isolate(), | 981 PROFILE(isolate(), |
| 980 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_PRE_MONOMORPHIC_TAG), | 982 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_PRE_MONOMORPHIC_TAG), |
| 981 *code, code->arguments_count())); | 983 *code, code->arguments_count())); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1001 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG), | 1003 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG), |
| 1002 *code, code->arguments_count())); | 1004 *code, code->arguments_count())); |
| 1003 GDBJIT(AddCode(GDBJITInterface::CALL_NORMAL, *code)); | 1005 GDBJIT(AddCode(GDBJITInterface::CALL_NORMAL, *code)); |
| 1004 return code; | 1006 return code; |
| 1005 } | 1007 } |
| 1006 | 1008 |
| 1007 | 1009 |
| 1008 Handle<Code> StubCompiler::CompileCallMegamorphic(Code::Flags flags) { | 1010 Handle<Code> StubCompiler::CompileCallMegamorphic(Code::Flags flags) { |
| 1009 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1011 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
| 1010 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1012 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
| 1011 Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); | 1013 ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); |
| 1012 if (kind == Code::CALL_IC) { | 1014 if (kind == Code::CALL_IC) { |
| 1013 CallIC::GenerateMegamorphic(masm(), argc, extra_state); | 1015 CallIC::GenerateMegamorphic(masm(), argc, extra_state); |
| 1014 } else { | 1016 } else { |
| 1015 KeyedCallIC::GenerateMegamorphic(masm(), argc); | 1017 KeyedCallIC::GenerateMegamorphic(masm(), argc); |
| 1016 } | 1018 } |
| 1017 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMegamorphic"); | 1019 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMegamorphic"); |
| 1018 isolate()->counters()->call_megamorphic_stubs()->Increment(); | 1020 isolate()->counters()->call_megamorphic_stubs()->Increment(); |
| 1019 PROFILE(isolate(), | 1021 PROFILE(isolate(), |
| 1020 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG), | 1022 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG), |
| 1021 *code, code->arguments_count())); | 1023 *code, code->arguments_count())); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1033 CALL_MEGAMORPHIC_TAG), | 1035 CALL_MEGAMORPHIC_TAG), |
| 1034 *code, code->arguments_count())); | 1036 *code, code->arguments_count())); |
| 1035 GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, *code)); | 1037 GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, *code)); |
| 1036 return code; | 1038 return code; |
| 1037 } | 1039 } |
| 1038 | 1040 |
| 1039 | 1041 |
| 1040 Handle<Code> StubCompiler::CompileCallMiss(Code::Flags flags) { | 1042 Handle<Code> StubCompiler::CompileCallMiss(Code::Flags flags) { |
| 1041 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1043 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
| 1042 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1044 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
| 1043 Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); | 1045 ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); |
| 1044 if (kind == Code::CALL_IC) { | 1046 if (kind == Code::CALL_IC) { |
| 1045 CallIC::GenerateMiss(masm(), argc, extra_state); | 1047 CallIC::GenerateMiss(masm(), argc, extra_state); |
| 1046 } else { | 1048 } else { |
| 1047 KeyedCallIC::GenerateMiss(masm(), argc); | 1049 KeyedCallIC::GenerateMiss(masm(), argc); |
| 1048 } | 1050 } |
| 1049 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMiss"); | 1051 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMiss"); |
| 1050 isolate()->counters()->call_megamorphic_stubs()->Increment(); | 1052 isolate()->counters()->call_megamorphic_stubs()->Increment(); |
| 1051 PROFILE(isolate(), | 1053 PROFILE(isolate(), |
| 1052 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MISS_TAG), | 1054 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MISS_TAG), |
| 1053 *code, code->arguments_count())); | 1055 *code, code->arguments_count())); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1068 } | 1070 } |
| 1069 | 1071 |
| 1070 | 1072 |
| 1071 Handle<Code> StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) { | 1073 Handle<Code> StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) { |
| 1072 // Use the same code for the the step in preparations as we do for the | 1074 // Use the same code for the the step in preparations as we do for the |
| 1073 // miss case. | 1075 // miss case. |
| 1074 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1076 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
| 1075 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1077 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
| 1076 if (kind == Code::CALL_IC) { | 1078 if (kind == Code::CALL_IC) { |
| 1077 // For the debugger extra ic state is irrelevant. | 1079 // For the debugger extra ic state is irrelevant. |
| 1078 CallIC::GenerateMiss(masm(), argc, Code::kNoExtraICState); | 1080 CallIC::GenerateMiss(masm(), argc, kNoExtraICState); |
| 1079 } else { | 1081 } else { |
| 1080 KeyedCallIC::GenerateMiss(masm(), argc); | 1082 KeyedCallIC::GenerateMiss(masm(), argc); |
| 1081 } | 1083 } |
| 1082 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn"); | 1084 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn"); |
| 1083 PROFILE(isolate(), | 1085 PROFILE(isolate(), |
| 1084 CodeCreateEvent( | 1086 CodeCreateEvent( |
| 1085 CALL_LOGGER_TAG(kind, CALL_DEBUG_PREPARE_STEP_IN_TAG), | 1087 CALL_LOGGER_TAG(kind, CALL_DEBUG_PREPARE_STEP_IN_TAG), |
| 1086 *code, | 1088 *code, |
| 1087 code->arguments_count())); | 1089 code->arguments_count())); |
| 1088 return code; | 1090 return code; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1119 holder->LocalLookupRealNamedProperty(*name, lookup); | 1121 holder->LocalLookupRealNamedProperty(*name, lookup); |
| 1120 if (lookup->IsFound()) return; | 1122 if (lookup->IsFound()) return; |
| 1121 if (holder->GetPrototype()->IsNull()) return; | 1123 if (holder->GetPrototype()->IsNull()) return; |
| 1122 holder->GetPrototype()->Lookup(*name, lookup); | 1124 holder->GetPrototype()->Lookup(*name, lookup); |
| 1123 } | 1125 } |
| 1124 | 1126 |
| 1125 | 1127 |
| 1126 #define __ ACCESS_MASM(masm()) | 1128 #define __ ACCESS_MASM(masm()) |
| 1127 | 1129 |
| 1128 | 1130 |
| 1131 void CallStubCompiler::HandlerFrontendFooter(Label* miss) { |
| 1132 __ bind(miss); |
| 1133 GenerateMissBranch(); |
| 1134 } |
| 1135 |
| 1136 |
| 1129 Register LoadStubCompiler::HandlerFrontendHeader( | 1137 Register LoadStubCompiler::HandlerFrontendHeader( |
| 1130 Handle<Type> type, | 1138 Handle<Type> type, |
| 1131 Register object_reg, | 1139 Register object_reg, |
| 1132 Handle<JSObject> holder, | 1140 Handle<JSObject> holder, |
| 1133 Handle<Name> name, | 1141 Handle<Name> name, |
| 1134 Label* miss) { | 1142 Label* miss) { |
| 1135 PrototypeCheckType check_type = CHECK_ALL_MAPS; | 1143 PrototypeCheckType check_type = CHECK_ALL_MAPS; |
| 1136 int function_index = -1; | 1144 int function_index = -1; |
| 1137 if (type->Is(Type::String())) { | 1145 if (type->Is(Type::String())) { |
| 1138 function_index = Context::STRING_FUNCTION_INDEX; | 1146 function_index = Context::STRING_FUNCTION_INDEX; |
| (...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1672 | 1680 |
| 1673 void KeyedStoreStubCompiler::GenerateStoreDictionaryElement( | 1681 void KeyedStoreStubCompiler::GenerateStoreDictionaryElement( |
| 1674 MacroAssembler* masm) { | 1682 MacroAssembler* masm) { |
| 1675 KeyedStoreIC::GenerateSlow(masm); | 1683 KeyedStoreIC::GenerateSlow(masm); |
| 1676 } | 1684 } |
| 1677 | 1685 |
| 1678 | 1686 |
| 1679 CallStubCompiler::CallStubCompiler(Isolate* isolate, | 1687 CallStubCompiler::CallStubCompiler(Isolate* isolate, |
| 1680 int argc, | 1688 int argc, |
| 1681 Code::Kind kind, | 1689 Code::Kind kind, |
| 1682 Code::ExtraICState extra_state, | 1690 ExtraICState extra_state, |
| 1683 InlineCacheHolderFlag cache_holder) | 1691 InlineCacheHolderFlag cache_holder) |
| 1684 : StubCompiler(isolate), | 1692 : StubCompiler(isolate), |
| 1685 arguments_(argc), | 1693 arguments_(argc), |
| 1686 kind_(kind), | 1694 kind_(kind), |
| 1687 extra_state_(extra_state), | 1695 extra_state_(extra_state), |
| 1688 cache_holder_(cache_holder) { | 1696 cache_holder_(cache_holder) { |
| 1689 } | 1697 } |
| 1690 | 1698 |
| 1691 | 1699 |
| 1692 bool CallStubCompiler::HasCustomCallGenerator(Handle<JSFunction> function) { | 1700 bool CallStubCompiler::HasCustomCallGenerator(Handle<JSFunction> function) { |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1833 Handle<FunctionTemplateInfo>( | 1841 Handle<FunctionTemplateInfo>( |
| 1834 FunctionTemplateInfo::cast(signature->receiver())); | 1842 FunctionTemplateInfo::cast(signature->receiver())); |
| 1835 } | 1843 } |
| 1836 } | 1844 } |
| 1837 | 1845 |
| 1838 is_simple_api_call_ = true; | 1846 is_simple_api_call_ = true; |
| 1839 } | 1847 } |
| 1840 | 1848 |
| 1841 | 1849 |
| 1842 } } // namespace v8::internal | 1850 } } // namespace v8::internal |
| OLD | NEW |