| 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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 // Update primary cache. | 93 // Update primary cache. |
| 94 primary->key = name; | 94 primary->key = name; |
| 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_map, | 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_map->FindInCodeCache(*name, flags), | 109 Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags), isolate_); |
| 110 isolate_); | |
| 111 if (probe->IsCode()) return Handle<Code>::cast(probe); | 110 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| 112 return Handle<Code>::null(); | 111 return Handle<Code>::null(); |
| 113 } | 112 } |
| 114 | 113 |
| 115 | 114 |
| 116 Handle<Code> StubCache::FindHandler(Handle<Name> name, | 115 Handle<Code> StubCache::FindHandler(Handle<Name> name, |
| 117 Handle<HeapObject> stub_holder, | 116 Handle<Map> stub_holder, |
| 118 Code::Kind kind, | 117 Code::Kind kind, |
| 119 InlineCacheHolderFlag cache_holder, | 118 InlineCacheHolderFlag cache_holder) { |
| 120 StrictModeFlag strict_mode) { | |
| 121 Code::ExtraICState extra_ic_state = Code::kNoExtraICState; | |
| 122 if (kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC) { | |
| 123 extra_ic_state = Code::ComputeExtraICState( | |
| 124 STANDARD_STORE, strict_mode); | |
| 125 } | |
| 126 Code::Flags flags = Code::ComputeMonomorphicFlags( | 119 Code::Flags flags = Code::ComputeMonomorphicFlags( |
| 127 Code::HANDLER, extra_ic_state, cache_holder, Code::NORMAL, kind); | 120 Code::HANDLER, kNoExtraICState, cache_holder, Code::NORMAL, kind); |
| 128 | 121 |
| 129 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags), | 122 Handle<Object> probe(stub_holder->FindInCodeCache(*name, flags), isolate_); |
| 130 isolate_); | |
| 131 if (probe->IsCode()) return Handle<Code>::cast(probe); | 123 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| 132 return Handle<Code>::null(); | 124 return Handle<Code>::null(); |
| 133 } | 125 } |
| 134 | 126 |
| 135 | 127 |
| 136 Handle<Code> StubCache::ComputeMonomorphicIC(Handle<Name> name, | 128 Handle<Code> StubCache::ComputeMonomorphicIC( |
| 137 Handle<Type> type, | 129 Handle<Name> name, |
| 138 Handle<Code> handler, | 130 Handle<Type> type, |
| 139 StrictModeFlag strict_mode) { | 131 Handle<Code> handler, |
| 132 ExtraICState extra_ic_state) { |
| 140 Code::Kind kind = handler->handler_kind(); | 133 Code::Kind kind = handler->handler_kind(); |
| 141 InlineCacheHolderFlag flag = IC::GetCodeCacheFlag(*type); | 134 InlineCacheHolderFlag flag = IC::GetCodeCacheFlag(*type); |
| 142 | 135 |
| 143 Handle<Map> stub_holder; | 136 Handle<Map> stub_holder; |
| 144 Handle<Code> ic; | 137 Handle<Code> ic; |
| 145 // 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 |
| 146 // 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, |
| 147 // for a single name. Hence, turn off caching of the IC. | 140 // for a single name. Hence, turn off caching of the IC. |
| 148 bool can_be_cached = !type->Is(Type::String()); | 141 bool can_be_cached = !type->Is(Type::String()); |
| 149 if (can_be_cached) { | 142 if (can_be_cached) { |
| 150 stub_holder = IC::GetCodeCacheHolder(flag, *type, isolate()); | 143 stub_holder = IC::GetCodeCacheHolder(flag, *type, isolate()); |
| 151 ic = FindIC(name, stub_holder, kind, strict_mode, flag); | 144 ic = FindIC(name, stub_holder, kind, extra_ic_state, flag); |
| 152 if (!ic.is_null()) return ic; | 145 if (!ic.is_null()) return ic; |
| 153 } | 146 } |
| 154 | 147 |
| 155 if (kind == Code::LOAD_IC) { | 148 if (kind == Code::LOAD_IC) { |
| 156 LoadStubCompiler ic_compiler(isolate(), flag); | 149 LoadStubCompiler ic_compiler(isolate(), flag); |
| 157 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); | 150 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); |
| 158 } else if (kind == Code::KEYED_LOAD_IC) { | 151 } else if (kind == Code::KEYED_LOAD_IC) { |
| 159 KeyedLoadStubCompiler ic_compiler(isolate(), flag); | 152 KeyedLoadStubCompiler ic_compiler(isolate(), flag); |
| 160 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); | 153 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); |
| 161 } else if (kind == Code::STORE_IC) { | 154 } else if (kind == Code::STORE_IC) { |
| 162 StoreStubCompiler ic_compiler(isolate(), strict_mode); | 155 StoreStubCompiler ic_compiler(isolate(), extra_ic_state); |
| 163 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); | 156 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); |
| 164 } else { | 157 } else { |
| 165 ASSERT(kind == Code::KEYED_STORE_IC); | 158 ASSERT(kind == Code::KEYED_STORE_IC); |
| 166 KeyedStoreStubCompiler ic_compiler(isolate(), strict_mode, STANDARD_STORE); | 159 ASSERT(STANDARD_STORE == |
| 160 KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state)); |
| 161 KeyedStoreStubCompiler ic_compiler(isolate(), extra_ic_state); |
| 167 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); | 162 ic = ic_compiler.CompileMonomorphicIC(type, handler, name); |
| 168 } | 163 } |
| 169 | 164 |
| 170 if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic); | 165 if (can_be_cached) Map::UpdateCodeCache(stub_holder, name, ic); |
| 171 return ic; | 166 return ic; |
| 172 } | 167 } |
| 173 | 168 |
| 174 | 169 |
| 175 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name, | 170 Handle<Code> StubCache::ComputeLoadNonexistent(Handle<Name> name, |
| 176 Handle<Object> object) { | 171 Handle<Type> type) { |
| 177 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object); | 172 InlineCacheHolderFlag flag = IC::GetCodeCacheFlag(*type); |
| 178 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder( | 173 Handle<Map> stub_holder = IC::GetCodeCacheHolder(flag, *type, isolate()); |
| 179 isolate(), *object, cache_holder)); | 174 // If no dictionary mode objects are present in the prototype chain, the load |
| 180 // If no global objects are present in the prototype chain, the load | 175 // nonexistent IC stub can be shared for all names for a given map and we use |
| 181 // nonexistent IC stub can be shared for all names for a given map | 176 // the empty string for the map cache in that case. If there are dictionary |
| 182 // and we use the empty string for the map cache in that case. If | 177 // mode objects involved, we need to do negative lookups in the stub and |
| 183 // there are global objects involved, we need to check global | 178 // therefore the stub will be specific to the name. |
| 184 // property cells in the stub and therefore the stub will be | 179 Handle<Map> current_map = stub_holder; |
| 185 // specific to the name. | 180 Handle<Name> cache_name = current_map->is_dictionary_map() |
| 186 Handle<Name> cache_name = factory()->empty_string(); | 181 ? name : Handle<Name>::cast(isolate()->factory()->empty_string()); |
| 187 Handle<JSObject> current; | 182 Handle<Object> next(current_map->prototype(), isolate()); |
| 188 Handle<Object> next = stub_holder; | 183 Handle<JSObject> last = Handle<JSObject>::null(); |
| 189 Handle<JSGlobalObject> global; | 184 while (!next->IsNull()) { |
| 190 do { | 185 last = Handle<JSObject>::cast(next); |
| 191 current = Handle<JSObject>::cast(next); | 186 next = handle(current_map->prototype(), isolate()); |
| 192 next = Handle<Object>(current->GetPrototype(), isolate_); | 187 current_map = handle(Handle<HeapObject>::cast(next)->map()); |
| 193 if (current->IsJSGlobalObject()) { | 188 if (current_map->is_dictionary_map()) cache_name = name; |
| 194 global = Handle<JSGlobalObject>::cast(current); | 189 } |
| 195 cache_name = name; | |
| 196 } else if (!current->HasFastProperties()) { | |
| 197 cache_name = name; | |
| 198 } | |
| 199 } while (!next->IsNull()); | |
| 200 | 190 |
| 201 // Compile the stub that is either shared for all names or | 191 // Compile the stub that is either shared for all names or |
| 202 // name specific if there are global objects involved. | 192 // name specific if there are global objects involved. |
| 203 Handle<Code> handler = FindHandler( | 193 Handle<Code> handler = FindHandler( |
| 204 cache_name, stub_holder, Code::LOAD_IC, cache_holder); | 194 cache_name, stub_holder, Code::LOAD_IC, flag); |
| 205 if (!handler.is_null()) return handler; | 195 if (!handler.is_null()) return handler; |
| 206 | 196 |
| 207 LoadStubCompiler compiler(isolate_, cache_holder); | 197 LoadStubCompiler compiler(isolate_, flag); |
| 208 handler = | 198 handler = compiler.CompileLoadNonexistent(type, last, cache_name); |
| 209 compiler.CompileLoadNonexistent(object, current, cache_name, global); | 199 Map::UpdateCodeCache(stub_holder, cache_name, handler); |
| 210 HeapObject::UpdateMapCodeCache(stub_holder, cache_name, handler); | |
| 211 return handler; | 200 return handler; |
| 212 } | 201 } |
| 213 | 202 |
| 214 | 203 |
| 215 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) { | 204 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) { |
| 216 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); | 205 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); |
| 217 Handle<Name> name = | 206 Handle<Name> name = |
| 218 isolate()->factory()->KeyedLoadElementMonomorphic_string(); | 207 isolate()->factory()->KeyedLoadElementMonomorphic_string(); |
| 219 | 208 |
| 220 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); | 209 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); |
| 221 if (probe->IsCode()) return Handle<Code>::cast(probe); | 210 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| 222 | 211 |
| 223 KeyedLoadStubCompiler compiler(isolate()); | 212 KeyedLoadStubCompiler compiler(isolate()); |
| 224 Handle<Code> code = compiler.CompileLoadElement(receiver_map); | 213 Handle<Code> code = compiler.CompileLoadElement(receiver_map); |
| 225 | 214 |
| 226 Map::UpdateCodeCache(receiver_map, name, code); | 215 Map::UpdateCodeCache(receiver_map, name, code); |
| 227 return code; | 216 return code; |
| 228 } | 217 } |
| 229 | 218 |
| 230 | 219 |
| 231 Handle<Code> StubCache::ComputeKeyedStoreElement( | 220 Handle<Code> StubCache::ComputeKeyedStoreElement( |
| 232 Handle<Map> receiver_map, | 221 Handle<Map> receiver_map, |
| 233 StrictModeFlag strict_mode, | 222 StrictModeFlag strict_mode, |
| 234 KeyedAccessStoreMode store_mode) { | 223 KeyedAccessStoreMode store_mode) { |
| 235 Code::ExtraICState extra_state = | 224 ExtraICState extra_state = |
| 236 Code::ComputeExtraICState(store_mode, strict_mode); | 225 KeyedStoreIC::ComputeExtraICState(strict_mode, store_mode); |
| 237 Code::Flags flags = Code::ComputeMonomorphicFlags( | 226 Code::Flags flags = Code::ComputeMonomorphicFlags( |
| 238 Code::KEYED_STORE_IC, extra_state); | 227 Code::KEYED_STORE_IC, extra_state); |
| 239 | 228 |
| 240 ASSERT(store_mode == STANDARD_STORE || | 229 ASSERT(store_mode == STANDARD_STORE || |
| 241 store_mode == STORE_AND_GROW_NO_TRANSITION || | 230 store_mode == STORE_AND_GROW_NO_TRANSITION || |
| 242 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || | 231 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || |
| 243 store_mode == STORE_NO_TRANSITION_HANDLE_COW); | 232 store_mode == STORE_NO_TRANSITION_HANDLE_COW); |
| 244 | 233 |
| 245 Handle<String> name = | 234 Handle<String> name = |
| 246 isolate()->factory()->KeyedStoreElementMonomorphic_string(); | 235 isolate()->factory()->KeyedStoreElementMonomorphic_string(); |
| 247 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); | 236 Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate_); |
| 248 if (probe->IsCode()) return Handle<Code>::cast(probe); | 237 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| 249 | 238 |
| 250 KeyedStoreStubCompiler compiler(isolate(), strict_mode, store_mode); | 239 KeyedStoreStubCompiler compiler(isolate(), extra_state); |
| 251 Handle<Code> code = compiler.CompileStoreElement(receiver_map); | 240 Handle<Code> code = compiler.CompileStoreElement(receiver_map); |
| 252 | 241 |
| 253 Map::UpdateCodeCache(receiver_map, name, code); | 242 Map::UpdateCodeCache(receiver_map, name, code); |
| 254 ASSERT(Code::GetKeyedAccessStoreMode(code->extra_ic_state()) == store_mode); | 243 ASSERT(KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state()) |
| 244 == store_mode); |
| 255 return code; | 245 return code; |
| 256 } | 246 } |
| 257 | 247 |
| 258 | 248 |
| 259 #define CALL_LOGGER_TAG(kind, type) \ | 249 #define CALL_LOGGER_TAG(kind, type) \ |
| 260 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) | 250 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) |
| 261 | 251 |
| 262 Handle<Code> StubCache::ComputeCallConstant(int argc, | 252 Handle<Code> StubCache::ComputeCallConstant(int argc, |
| 263 Code::Kind kind, | 253 Code::Kind kind, |
| 264 Code::ExtraICState extra_state, | 254 ExtraICState extra_state, |
| 265 Handle<Name> name, | 255 Handle<Name> name, |
| 266 Handle<Object> object, | 256 Handle<Object> object, |
| 267 Handle<JSObject> holder, | 257 Handle<JSObject> holder, |
| 268 Handle<JSFunction> function) { | 258 Handle<JSFunction> function) { |
| 269 // Compute the check type and the map. | 259 // Compute the check type and the map. |
| 270 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object); | 260 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object); |
| 271 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder( | 261 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder( |
| 272 isolate_, *object, cache_holder)); | 262 isolate_, *object, cache_holder)); |
| 273 | 263 |
| 274 // 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... |
| 308 | 298 |
| 309 if (CallStubCompiler::CanBeCached(function)) { | 299 if (CallStubCompiler::CanBeCached(function)) { |
| 310 HeapObject::UpdateMapCodeCache(stub_holder, name, code); | 300 HeapObject::UpdateMapCodeCache(stub_holder, name, code); |
| 311 } | 301 } |
| 312 return code; | 302 return code; |
| 313 } | 303 } |
| 314 | 304 |
| 315 | 305 |
| 316 Handle<Code> StubCache::ComputeCallField(int argc, | 306 Handle<Code> StubCache::ComputeCallField(int argc, |
| 317 Code::Kind kind, | 307 Code::Kind kind, |
| 318 Code::ExtraICState extra_state, | 308 ExtraICState extra_state, |
| 319 Handle<Name> name, | 309 Handle<Name> name, |
| 320 Handle<Object> object, | 310 Handle<Object> object, |
| 321 Handle<JSObject> holder, | 311 Handle<JSObject> holder, |
| 322 PropertyIndex index) { | 312 PropertyIndex index) { |
| 323 // Compute the check type and the map. | 313 // Compute the check type and the map. |
| 324 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object); | 314 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object); |
| 325 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder( | 315 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder( |
| 326 isolate_, *object, cache_holder)); | 316 isolate_, *object, cache_holder)); |
| 327 | 317 |
| 328 // 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... |
| 347 PROFILE(isolate_, | 337 PROFILE(isolate_, |
| 348 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); | 338 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); |
| 349 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); | 339 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); |
| 350 HeapObject::UpdateMapCodeCache(stub_holder, name, code); | 340 HeapObject::UpdateMapCodeCache(stub_holder, name, code); |
| 351 return code; | 341 return code; |
| 352 } | 342 } |
| 353 | 343 |
| 354 | 344 |
| 355 Handle<Code> StubCache::ComputeCallInterceptor(int argc, | 345 Handle<Code> StubCache::ComputeCallInterceptor(int argc, |
| 356 Code::Kind kind, | 346 Code::Kind kind, |
| 357 Code::ExtraICState extra_state, | 347 ExtraICState extra_state, |
| 358 Handle<Name> name, | 348 Handle<Name> name, |
| 359 Handle<Object> object, | 349 Handle<Object> object, |
| 360 Handle<JSObject> holder) { | 350 Handle<JSObject> holder) { |
| 361 // Compute the check type and the map. | 351 // Compute the check type and the map. |
| 362 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object); | 352 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object); |
| 363 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder( | 353 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder( |
| 364 isolate_, *object, cache_holder)); | 354 isolate_, *object, cache_holder)); |
| 365 | 355 |
| 366 // 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 |
| 367 // 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... |
| 385 PROFILE(isolate(), | 375 PROFILE(isolate(), |
| 386 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); | 376 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); |
| 387 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); | 377 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); |
| 388 HeapObject::UpdateMapCodeCache(stub_holder, name, code); | 378 HeapObject::UpdateMapCodeCache(stub_holder, name, code); |
| 389 return code; | 379 return code; |
| 390 } | 380 } |
| 391 | 381 |
| 392 | 382 |
| 393 Handle<Code> StubCache::ComputeCallGlobal(int argc, | 383 Handle<Code> StubCache::ComputeCallGlobal(int argc, |
| 394 Code::Kind kind, | 384 Code::Kind kind, |
| 395 Code::ExtraICState extra_state, | 385 ExtraICState extra_state, |
| 396 Handle<Name> name, | 386 Handle<Name> name, |
| 397 Handle<JSObject> receiver, | 387 Handle<JSObject> receiver, |
| 398 Handle<GlobalObject> holder, | 388 Handle<GlobalObject> holder, |
| 399 Handle<PropertyCell> cell, | 389 Handle<PropertyCell> cell, |
| 400 Handle<JSFunction> function) { | 390 Handle<JSFunction> function) { |
| 401 Code::Flags flags = Code::ComputeMonomorphicFlags( | 391 Code::Flags flags = Code::ComputeMonomorphicFlags( |
| 402 kind, extra_state, OWN_MAP, Code::NORMAL, argc); | 392 kind, extra_state, OWN_MAP, Code::NORMAL, argc); |
| 403 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), | 393 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags), |
| 404 isolate_); | 394 isolate_); |
| 405 if (probe->IsCode()) return Handle<Code>::cast(probe); | 395 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 423 UnseededNumberDictionary::Set(isolate->factory()->non_monomorphic_cache(), | 413 UnseededNumberDictionary::Set(isolate->factory()->non_monomorphic_cache(), |
| 424 code->flags(), | 414 code->flags(), |
| 425 code); | 415 code); |
| 426 isolate->heap()->public_set_non_monomorphic_cache(*dictionary); | 416 isolate->heap()->public_set_non_monomorphic_cache(*dictionary); |
| 427 } | 417 } |
| 428 | 418 |
| 429 | 419 |
| 430 Code* StubCache::FindCallInitialize(int argc, | 420 Code* StubCache::FindCallInitialize(int argc, |
| 431 RelocInfo::Mode mode, | 421 RelocInfo::Mode mode, |
| 432 Code::Kind kind) { | 422 Code::Kind kind) { |
| 433 Code::ExtraICState extra_state = | 423 ExtraICState extra_state = |
| 434 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) | | 424 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) | |
| 435 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT); | 425 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT |
| 426 ? CONTEXTUAL : NOT_CONTEXTUAL); |
| 436 Code::Flags flags = | 427 Code::Flags flags = |
| 437 Code::ComputeFlags(kind, UNINITIALIZED, extra_state, Code::NORMAL, argc); | 428 Code::ComputeFlags(kind, UNINITIALIZED, extra_state, Code::NORMAL, argc); |
| 438 UnseededNumberDictionary* dictionary = | 429 UnseededNumberDictionary* dictionary = |
| 439 isolate()->heap()->non_monomorphic_cache(); | 430 isolate()->heap()->non_monomorphic_cache(); |
| 440 int entry = dictionary->FindEntry(isolate(), flags); | 431 int entry = dictionary->FindEntry(isolate(), flags); |
| 441 ASSERT(entry != -1); | 432 ASSERT(entry != -1); |
| 442 Object* code = dictionary->ValueAt(entry); | 433 Object* code = dictionary->ValueAt(entry); |
| 443 // This might be called during the marking phase of the collector | 434 // This might be called during the marking phase of the collector |
| 444 // hence the unchecked cast. | 435 // hence the unchecked cast. |
| 445 return reinterpret_cast<Code*>(code); | 436 return reinterpret_cast<Code*>(code); |
| 446 } | 437 } |
| 447 | 438 |
| 448 | 439 |
| 449 Handle<Code> StubCache::ComputeCallInitialize(int argc, | 440 Handle<Code> StubCache::ComputeCallInitialize(int argc, |
| 450 RelocInfo::Mode mode, | 441 RelocInfo::Mode mode, |
| 451 Code::Kind kind) { | 442 Code::Kind kind) { |
| 452 Code::ExtraICState extra_state = | 443 ExtraICState extra_state = |
| 453 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) | | 444 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) | |
| 454 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT); | 445 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT |
| 446 ? CONTEXTUAL : NOT_CONTEXTUAL); |
| 455 Code::Flags flags = | 447 Code::Flags flags = |
| 456 Code::ComputeFlags(kind, UNINITIALIZED, extra_state, Code::NORMAL, argc); | 448 Code::ComputeFlags(kind, UNINITIALIZED, extra_state, Code::NORMAL, argc); |
| 457 Handle<UnseededNumberDictionary> cache = | 449 Handle<UnseededNumberDictionary> cache = |
| 458 isolate_->factory()->non_monomorphic_cache(); | 450 isolate_->factory()->non_monomorphic_cache(); |
| 459 int entry = cache->FindEntry(isolate_, flags); | 451 int entry = cache->FindEntry(isolate_, flags); |
| 460 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); | 452 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); |
| 461 | 453 |
| 462 StubCompiler compiler(isolate_); | 454 StubCompiler compiler(isolate_); |
| 463 Handle<Code> code = compiler.CompileCallInitialize(flags); | 455 Handle<Code> code = compiler.CompileCallInitialize(flags); |
| 464 FillCache(isolate_, code); | 456 FillCache(isolate_, code); |
| 465 return code; | 457 return code; |
| 466 } | 458 } |
| 467 | 459 |
| 468 | 460 |
| 469 Handle<Code> StubCache::ComputeCallInitialize(int argc, RelocInfo::Mode mode) { | 461 Handle<Code> StubCache::ComputeCallInitialize(int argc, RelocInfo::Mode mode) { |
| 470 return ComputeCallInitialize(argc, mode, Code::CALL_IC); | 462 return ComputeCallInitialize(argc, mode, Code::CALL_IC); |
| 471 } | 463 } |
| 472 | 464 |
| 473 | 465 |
| 474 Handle<Code> StubCache::ComputeKeyedCallInitialize(int argc) { | 466 Handle<Code> StubCache::ComputeKeyedCallInitialize(int argc) { |
| 475 return ComputeCallInitialize(argc, RelocInfo::CODE_TARGET, | 467 return ComputeCallInitialize(argc, RelocInfo::CODE_TARGET, |
| 476 Code::KEYED_CALL_IC); | 468 Code::KEYED_CALL_IC); |
| 477 } | 469 } |
| 478 | 470 |
| 479 | 471 |
| 480 Handle<Code> StubCache::ComputeCallPreMonomorphic( | 472 Handle<Code> StubCache::ComputeCallPreMonomorphic( |
| 481 int argc, | 473 int argc, |
| 482 Code::Kind kind, | 474 Code::Kind kind, |
| 483 Code::ExtraICState extra_state) { | 475 ExtraICState extra_state) { |
| 484 Code::Flags flags = | 476 Code::Flags flags = |
| 485 Code::ComputeFlags(kind, PREMONOMORPHIC, extra_state, Code::NORMAL, argc); | 477 Code::ComputeFlags(kind, PREMONOMORPHIC, extra_state, Code::NORMAL, argc); |
| 486 Handle<UnseededNumberDictionary> cache = | 478 Handle<UnseededNumberDictionary> cache = |
| 487 isolate_->factory()->non_monomorphic_cache(); | 479 isolate_->factory()->non_monomorphic_cache(); |
| 488 int entry = cache->FindEntry(isolate_, flags); | 480 int entry = cache->FindEntry(isolate_, flags); |
| 489 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); | 481 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); |
| 490 | 482 |
| 491 StubCompiler compiler(isolate_); | 483 StubCompiler compiler(isolate_); |
| 492 Handle<Code> code = compiler.CompileCallPreMonomorphic(flags); | 484 Handle<Code> code = compiler.CompileCallPreMonomorphic(flags); |
| 493 FillCache(isolate_, code); | 485 FillCache(isolate_, code); |
| 494 return code; | 486 return code; |
| 495 } | 487 } |
| 496 | 488 |
| 497 | 489 |
| 498 Handle<Code> StubCache::ComputeCallNormal(int argc, | 490 Handle<Code> StubCache::ComputeCallNormal(int argc, |
| 499 Code::Kind kind, | 491 Code::Kind kind, |
| 500 Code::ExtraICState extra_state) { | 492 ExtraICState extra_state) { |
| 501 Code::Flags flags = | 493 Code::Flags flags = |
| 502 Code::ComputeFlags(kind, MONOMORPHIC, extra_state, Code::NORMAL, argc); | 494 Code::ComputeFlags(kind, MONOMORPHIC, extra_state, Code::NORMAL, argc); |
| 503 Handle<UnseededNumberDictionary> cache = | 495 Handle<UnseededNumberDictionary> cache = |
| 504 isolate_->factory()->non_monomorphic_cache(); | 496 isolate_->factory()->non_monomorphic_cache(); |
| 505 int entry = cache->FindEntry(isolate_, flags); | 497 int entry = cache->FindEntry(isolate_, flags); |
| 506 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); | 498 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); |
| 507 | 499 |
| 508 StubCompiler compiler(isolate_); | 500 StubCompiler compiler(isolate_); |
| 509 Handle<Code> code = compiler.CompileCallNormal(flags); | 501 Handle<Code> code = compiler.CompileCallNormal(flags); |
| 510 FillCache(isolate_, code); | 502 FillCache(isolate_, code); |
| 511 return code; | 503 return code; |
| 512 } | 504 } |
| 513 | 505 |
| 514 | 506 |
| 515 Handle<Code> StubCache::ComputeCallArguments(int argc) { | 507 Handle<Code> StubCache::ComputeCallArguments(int argc) { |
| 516 Code::Flags flags = | 508 Code::Flags flags = |
| 517 Code::ComputeFlags(Code::KEYED_CALL_IC, MEGAMORPHIC, | 509 Code::ComputeFlags(Code::KEYED_CALL_IC, MEGAMORPHIC, |
| 518 Code::kNoExtraICState, Code::NORMAL, argc); | 510 kNoExtraICState, Code::NORMAL, argc); |
| 519 Handle<UnseededNumberDictionary> cache = | 511 Handle<UnseededNumberDictionary> cache = |
| 520 isolate_->factory()->non_monomorphic_cache(); | 512 isolate_->factory()->non_monomorphic_cache(); |
| 521 int entry = cache->FindEntry(isolate_, flags); | 513 int entry = cache->FindEntry(isolate_, flags); |
| 522 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); | 514 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); |
| 523 | 515 |
| 524 StubCompiler compiler(isolate_); | 516 StubCompiler compiler(isolate_); |
| 525 Handle<Code> code = compiler.CompileCallArguments(flags); | 517 Handle<Code> code = compiler.CompileCallArguments(flags); |
| 526 FillCache(isolate_, code); | 518 FillCache(isolate_, code); |
| 527 return code; | 519 return code; |
| 528 } | 520 } |
| 529 | 521 |
| 530 | 522 |
| 531 Handle<Code> StubCache::ComputeCallMegamorphic( | 523 Handle<Code> StubCache::ComputeCallMegamorphic( |
| 532 int argc, | 524 int argc, |
| 533 Code::Kind kind, | 525 Code::Kind kind, |
| 534 Code::ExtraICState extra_state) { | 526 ExtraICState extra_state) { |
| 535 Code::Flags flags = | 527 Code::Flags flags = |
| 536 Code::ComputeFlags(kind, MEGAMORPHIC, extra_state, | 528 Code::ComputeFlags(kind, MEGAMORPHIC, extra_state, |
| 537 Code::NORMAL, argc); | 529 Code::NORMAL, argc); |
| 538 Handle<UnseededNumberDictionary> cache = | 530 Handle<UnseededNumberDictionary> cache = |
| 539 isolate_->factory()->non_monomorphic_cache(); | 531 isolate_->factory()->non_monomorphic_cache(); |
| 540 int entry = cache->FindEntry(isolate_, flags); | 532 int entry = cache->FindEntry(isolate_, flags); |
| 541 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); | 533 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); |
| 542 | 534 |
| 543 StubCompiler compiler(isolate_); | 535 StubCompiler compiler(isolate_); |
| 544 Handle<Code> code = compiler.CompileCallMegamorphic(flags); | 536 Handle<Code> code = compiler.CompileCallMegamorphic(flags); |
| 545 FillCache(isolate_, code); | 537 FillCache(isolate_, code); |
| 546 return code; | 538 return code; |
| 547 } | 539 } |
| 548 | 540 |
| 549 | 541 |
| 550 Handle<Code> StubCache::ComputeCallMiss(int argc, | 542 Handle<Code> StubCache::ComputeCallMiss(int argc, |
| 551 Code::Kind kind, | 543 Code::Kind kind, |
| 552 Code::ExtraICState extra_state) { | 544 ExtraICState extra_state) { |
| 553 // 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 |
| 554 // 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. |
| 555 Code::Flags flags = | 547 Code::Flags flags = |
| 556 Code::ComputeFlags(kind, MONOMORPHIC_PROTOTYPE_FAILURE, extra_state, | 548 Code::ComputeFlags(kind, MONOMORPHIC_PROTOTYPE_FAILURE, extra_state, |
| 557 Code::NORMAL, argc, OWN_MAP); | 549 Code::NORMAL, argc, OWN_MAP); |
| 558 Handle<UnseededNumberDictionary> cache = | 550 Handle<UnseededNumberDictionary> cache = |
| 559 isolate_->factory()->non_monomorphic_cache(); | 551 isolate_->factory()->non_monomorphic_cache(); |
| 560 int entry = cache->FindEntry(isolate_, flags); | 552 int entry = cache->FindEntry(isolate_, flags); |
| 561 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); | 553 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); |
| 562 | 554 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 606 Handle<Code> code = compiler.CompilePolymorphicIC( | 598 Handle<Code> code = compiler.CompilePolymorphicIC( |
| 607 &types, &handlers, factory()->empty_string(), Code::NORMAL, ELEMENT); | 599 &types, &handlers, factory()->empty_string(), Code::NORMAL, ELEMENT); |
| 608 | 600 |
| 609 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment(); | 601 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment(); |
| 610 | 602 |
| 611 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); | 603 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); |
| 612 return code; | 604 return code; |
| 613 } | 605 } |
| 614 | 606 |
| 615 | 607 |
| 616 Handle<Code> StubCache::ComputePolymorphicIC(TypeHandleList* types, | 608 Handle<Code> StubCache::ComputePolymorphicIC( |
| 617 CodeHandleList* handlers, | 609 TypeHandleList* types, |
| 618 int number_of_valid_types, | 610 CodeHandleList* handlers, |
| 619 Handle<Name> name, | 611 int number_of_valid_types, |
| 620 StrictModeFlag strict_mode) { | 612 Handle<Name> name, |
| 613 ExtraICState extra_ic_state) { |
| 614 |
| 621 Handle<Code> handler = handlers->at(0); | 615 Handle<Code> handler = handlers->at(0); |
| 622 Code::Kind kind = handler->handler_kind(); | 616 Code::Kind kind = handler->handler_kind(); |
| 623 Code::StubType type = number_of_valid_types == 1 ? handler->type() | 617 Code::StubType type = number_of_valid_types == 1 ? handler->type() |
| 624 : Code::NORMAL; | 618 : Code::NORMAL; |
| 625 if (kind == Code::LOAD_IC) { | 619 if (kind == Code::LOAD_IC) { |
| 626 LoadStubCompiler ic_compiler(isolate_); | 620 LoadStubCompiler ic_compiler(isolate_); |
| 627 return ic_compiler.CompilePolymorphicIC( | 621 return ic_compiler.CompilePolymorphicIC( |
| 628 types, handlers, name, type, PROPERTY); | 622 types, handlers, name, type, PROPERTY); |
| 629 } else { | 623 } else { |
| 630 ASSERT(kind == Code::STORE_IC); | 624 ASSERT(kind == Code::STORE_IC); |
| 625 StrictModeFlag strict_mode = StoreIC::GetStrictMode(extra_ic_state); |
| 631 StoreStubCompiler ic_compiler(isolate_, strict_mode); | 626 StoreStubCompiler ic_compiler(isolate_, strict_mode); |
| 632 return ic_compiler.CompilePolymorphicIC( | 627 return ic_compiler.CompilePolymorphicIC( |
| 633 types, handlers, name, type, PROPERTY); | 628 types, handlers, name, type, PROPERTY); |
| 634 } | 629 } |
| 635 } | 630 } |
| 636 | 631 |
| 637 | 632 |
| 638 Handle<Code> StubCache::ComputeStoreElementPolymorphic( | 633 Handle<Code> StubCache::ComputeStoreElementPolymorphic( |
| 639 MapHandleList* receiver_maps, | 634 MapHandleList* receiver_maps, |
| 640 KeyedAccessStoreMode store_mode, | 635 KeyedAccessStoreMode store_mode, |
| 641 StrictModeFlag strict_mode) { | 636 StrictModeFlag strict_mode) { |
| 642 ASSERT(store_mode == STANDARD_STORE || | 637 ASSERT(store_mode == STANDARD_STORE || |
| 643 store_mode == STORE_AND_GROW_NO_TRANSITION || | 638 store_mode == STORE_AND_GROW_NO_TRANSITION || |
| 644 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || | 639 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || |
| 645 store_mode == STORE_NO_TRANSITION_HANDLE_COW); | 640 store_mode == STORE_NO_TRANSITION_HANDLE_COW); |
| 646 Handle<PolymorphicCodeCache> cache = | 641 Handle<PolymorphicCodeCache> cache = |
| 647 isolate_->factory()->polymorphic_code_cache(); | 642 isolate_->factory()->polymorphic_code_cache(); |
| 648 Code::ExtraICState extra_state = Code::ComputeExtraICState(store_mode, | 643 ExtraICState extra_state = KeyedStoreIC::ComputeExtraICState( |
| 649 strict_mode); | 644 strict_mode, store_mode); |
| 650 Code::Flags flags = | 645 Code::Flags flags = |
| 651 Code::ComputeFlags(Code::KEYED_STORE_IC, POLYMORPHIC, extra_state); | 646 Code::ComputeFlags(Code::KEYED_STORE_IC, POLYMORPHIC, extra_state); |
| 652 Handle<Object> probe = cache->Lookup(receiver_maps, flags); | 647 Handle<Object> probe = cache->Lookup(receiver_maps, flags); |
| 653 if (probe->IsCode()) return Handle<Code>::cast(probe); | 648 if (probe->IsCode()) return Handle<Code>::cast(probe); |
| 654 | 649 |
| 655 KeyedStoreStubCompiler compiler(isolate_, strict_mode, store_mode); | 650 KeyedStoreStubCompiler compiler(isolate_, extra_state); |
| 656 Handle<Code> code = compiler.CompileStoreElementPolymorphic(receiver_maps); | 651 Handle<Code> code = compiler.CompileStoreElementPolymorphic(receiver_maps); |
| 657 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); | 652 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); |
| 658 return code; | 653 return code; |
| 659 } | 654 } |
| 660 | 655 |
| 661 | 656 |
| 662 #ifdef ENABLE_DEBUGGER_SUPPORT | 657 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 663 Handle<Code> StubCache::ComputeCallDebugBreak(int argc, | 658 Handle<Code> StubCache::ComputeCallDebugBreak(int argc, |
| 664 Code::Kind kind) { | 659 Code::Kind kind) { |
| 665 // Extra IC state is irrelevant for debug break ICs. They jump to | 660 // Extra IC state is irrelevant for debug break ICs. They jump to |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 922 RETURN_IF_EMPTY_HANDLE(isolate, result); | 917 RETURN_IF_EMPTY_HANDLE(isolate, result); |
| 923 // 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 |
| 924 // 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 |
| 925 // function. | 920 // function. |
| 926 return *result; | 921 return *result; |
| 927 } | 922 } |
| 928 | 923 |
| 929 | 924 |
| 930 RUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty) { | 925 RUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty) { |
| 931 HandleScope scope(isolate); | 926 HandleScope scope(isolate); |
| 932 ASSERT(args.length() == 4); | 927 ASSERT(args.length() == 3); |
| 933 Handle<JSObject> recv(JSObject::cast(args[0])); | 928 StoreIC ic(IC::NO_EXTRA_FRAME, isolate); |
| 934 Handle<Name> name(Name::cast(args[1])); | 929 Handle<JSObject> receiver = args.at<JSObject>(0); |
| 935 Handle<Object> value(args[2], isolate); | 930 Handle<Name> name = args.at<Name>(1); |
| 936 ASSERT(args.smi_at(3) == kStrictMode || args.smi_at(3) == kNonStrictMode); | 931 Handle<Object> value = args.at<Object>(2); |
| 937 StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(3)); | 932 ASSERT(receiver->HasNamedInterceptor()); |
| 938 ASSERT(recv->HasNamedInterceptor()); | |
| 939 PropertyAttributes attr = NONE; | 933 PropertyAttributes attr = NONE; |
| 940 Handle<Object> result = JSObject::SetPropertyWithInterceptor( | 934 Handle<Object> result = JSObject::SetPropertyWithInterceptor( |
| 941 recv, name, value, attr, strict_mode); | 935 receiver, name, value, attr, ic.strict_mode()); |
| 942 RETURN_IF_EMPTY_HANDLE(isolate, result); | 936 RETURN_IF_EMPTY_HANDLE(isolate, result); |
| 943 return *result; | 937 return *result; |
| 944 } | 938 } |
| 945 | 939 |
| 946 | 940 |
| 947 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor) { | 941 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor) { |
| 948 JSObject* receiver = JSObject::cast(args[0]); | 942 JSObject* receiver = JSObject::cast(args[0]); |
| 949 ASSERT(args.smi_at(1) >= 0); | 943 ASSERT(args.smi_at(1) >= 0); |
| 950 uint32_t index = args.smi_at(1); | 944 uint32_t index = args.smi_at(1); |
| 951 return receiver->GetElementWithInterceptor(receiver, index); | 945 return receiver->GetElementWithInterceptor(receiver, index); |
| 952 } | 946 } |
| 953 | 947 |
| 954 | 948 |
| 955 Handle<Code> StubCompiler::CompileCallInitialize(Code::Flags flags) { | 949 Handle<Code> StubCompiler::CompileCallInitialize(Code::Flags flags) { |
| 956 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 950 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
| 957 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 951 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
| 958 Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); | 952 ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); |
| 959 if (kind == Code::CALL_IC) { | 953 if (kind == Code::CALL_IC) { |
| 960 CallIC::GenerateInitialize(masm(), argc, extra_state); | 954 CallIC::GenerateInitialize(masm(), argc, extra_state); |
| 961 } else { | 955 } else { |
| 962 KeyedCallIC::GenerateInitialize(masm(), argc); | 956 KeyedCallIC::GenerateInitialize(masm(), argc); |
| 963 } | 957 } |
| 964 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallInitialize"); | 958 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallInitialize"); |
| 965 isolate()->counters()->call_initialize_stubs()->Increment(); | 959 isolate()->counters()->call_initialize_stubs()->Increment(); |
| 966 PROFILE(isolate(), | 960 PROFILE(isolate(), |
| 967 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_INITIALIZE_TAG), | 961 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_INITIALIZE_TAG), |
| 968 *code, code->arguments_count())); | 962 *code, code->arguments_count())); |
| 969 GDBJIT(AddCode(GDBJITInterface::CALL_INITIALIZE, *code)); | 963 GDBJIT(AddCode(GDBJITInterface::CALL_INITIALIZE, *code)); |
| 970 return code; | 964 return code; |
| 971 } | 965 } |
| 972 | 966 |
| 973 | 967 |
| 974 Handle<Code> StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) { | 968 Handle<Code> StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) { |
| 975 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 969 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
| 976 // 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 |
| 977 // 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. |
| 978 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 972 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
| 979 Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); | 973 ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); |
| 980 if (kind == Code::CALL_IC) { | 974 if (kind == Code::CALL_IC) { |
| 981 CallIC::GenerateInitialize(masm(), argc, extra_state); | 975 CallIC::GenerateInitialize(masm(), argc, extra_state); |
| 982 } else { | 976 } else { |
| 983 KeyedCallIC::GenerateInitialize(masm(), argc); | 977 KeyedCallIC::GenerateInitialize(masm(), argc); |
| 984 } | 978 } |
| 985 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallPreMonomorphic"); | 979 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallPreMonomorphic"); |
| 986 isolate()->counters()->call_premonomorphic_stubs()->Increment(); | 980 isolate()->counters()->call_premonomorphic_stubs()->Increment(); |
| 987 PROFILE(isolate(), | 981 PROFILE(isolate(), |
| 988 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_PRE_MONOMORPHIC_TAG), | 982 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_PRE_MONOMORPHIC_TAG), |
| 989 *code, code->arguments_count())); | 983 *code, code->arguments_count())); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1009 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG), | 1003 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG), |
| 1010 *code, code->arguments_count())); | 1004 *code, code->arguments_count())); |
| 1011 GDBJIT(AddCode(GDBJITInterface::CALL_NORMAL, *code)); | 1005 GDBJIT(AddCode(GDBJITInterface::CALL_NORMAL, *code)); |
| 1012 return code; | 1006 return code; |
| 1013 } | 1007 } |
| 1014 | 1008 |
| 1015 | 1009 |
| 1016 Handle<Code> StubCompiler::CompileCallMegamorphic(Code::Flags flags) { | 1010 Handle<Code> StubCompiler::CompileCallMegamorphic(Code::Flags flags) { |
| 1017 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1011 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
| 1018 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1012 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
| 1019 Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); | 1013 ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); |
| 1020 if (kind == Code::CALL_IC) { | 1014 if (kind == Code::CALL_IC) { |
| 1021 CallIC::GenerateMegamorphic(masm(), argc, extra_state); | 1015 CallIC::GenerateMegamorphic(masm(), argc, extra_state); |
| 1022 } else { | 1016 } else { |
| 1023 KeyedCallIC::GenerateMegamorphic(masm(), argc); | 1017 KeyedCallIC::GenerateMegamorphic(masm(), argc); |
| 1024 } | 1018 } |
| 1025 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMegamorphic"); | 1019 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMegamorphic"); |
| 1026 isolate()->counters()->call_megamorphic_stubs()->Increment(); | 1020 isolate()->counters()->call_megamorphic_stubs()->Increment(); |
| 1027 PROFILE(isolate(), | 1021 PROFILE(isolate(), |
| 1028 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG), | 1022 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG), |
| 1029 *code, code->arguments_count())); | 1023 *code, code->arguments_count())); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1041 CALL_MEGAMORPHIC_TAG), | 1035 CALL_MEGAMORPHIC_TAG), |
| 1042 *code, code->arguments_count())); | 1036 *code, code->arguments_count())); |
| 1043 GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, *code)); | 1037 GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, *code)); |
| 1044 return code; | 1038 return code; |
| 1045 } | 1039 } |
| 1046 | 1040 |
| 1047 | 1041 |
| 1048 Handle<Code> StubCompiler::CompileCallMiss(Code::Flags flags) { | 1042 Handle<Code> StubCompiler::CompileCallMiss(Code::Flags flags) { |
| 1049 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1043 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
| 1050 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1044 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
| 1051 Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); | 1045 ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); |
| 1052 if (kind == Code::CALL_IC) { | 1046 if (kind == Code::CALL_IC) { |
| 1053 CallIC::GenerateMiss(masm(), argc, extra_state); | 1047 CallIC::GenerateMiss(masm(), argc, extra_state); |
| 1054 } else { | 1048 } else { |
| 1055 KeyedCallIC::GenerateMiss(masm(), argc); | 1049 KeyedCallIC::GenerateMiss(masm(), argc); |
| 1056 } | 1050 } |
| 1057 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMiss"); | 1051 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMiss"); |
| 1058 isolate()->counters()->call_megamorphic_stubs()->Increment(); | 1052 isolate()->counters()->call_megamorphic_stubs()->Increment(); |
| 1059 PROFILE(isolate(), | 1053 PROFILE(isolate(), |
| 1060 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MISS_TAG), | 1054 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MISS_TAG), |
| 1061 *code, code->arguments_count())); | 1055 *code, code->arguments_count())); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1076 } | 1070 } |
| 1077 | 1071 |
| 1078 | 1072 |
| 1079 Handle<Code> StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) { | 1073 Handle<Code> StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) { |
| 1080 // 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 |
| 1081 // miss case. | 1075 // miss case. |
| 1082 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1076 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
| 1083 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1077 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
| 1084 if (kind == Code::CALL_IC) { | 1078 if (kind == Code::CALL_IC) { |
| 1085 // For the debugger extra ic state is irrelevant. | 1079 // For the debugger extra ic state is irrelevant. |
| 1086 CallIC::GenerateMiss(masm(), argc, Code::kNoExtraICState); | 1080 CallIC::GenerateMiss(masm(), argc, kNoExtraICState); |
| 1087 } else { | 1081 } else { |
| 1088 KeyedCallIC::GenerateMiss(masm(), argc); | 1082 KeyedCallIC::GenerateMiss(masm(), argc); |
| 1089 } | 1083 } |
| 1090 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn"); | 1084 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn"); |
| 1091 PROFILE(isolate(), | 1085 PROFILE(isolate(), |
| 1092 CodeCreateEvent( | 1086 CodeCreateEvent( |
| 1093 CALL_LOGGER_TAG(kind, CALL_DEBUG_PREPARE_STEP_IN_TAG), | 1087 CALL_LOGGER_TAG(kind, CALL_DEBUG_PREPARE_STEP_IN_TAG), |
| 1094 *code, | 1088 *code, |
| 1095 code->arguments_count())); | 1089 code->arguments_count())); |
| 1096 return code; | 1090 return code; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1109 #ifdef ENABLE_DISASSEMBLER | 1103 #ifdef ENABLE_DISASSEMBLER |
| 1110 if (FLAG_print_code_stubs) code->Disassemble(name); | 1104 if (FLAG_print_code_stubs) code->Disassemble(name); |
| 1111 #endif | 1105 #endif |
| 1112 return code; | 1106 return code; |
| 1113 } | 1107 } |
| 1114 | 1108 |
| 1115 | 1109 |
| 1116 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags, | 1110 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags, |
| 1117 Handle<Name> name) { | 1111 Handle<Name> name) { |
| 1118 return (FLAG_print_code_stubs && !name.is_null() && name->IsString()) | 1112 return (FLAG_print_code_stubs && !name.is_null() && name->IsString()) |
| 1119 ? GetCodeWithFlags(flags, *Handle<String>::cast(name)->ToCString()) | 1113 ? GetCodeWithFlags(flags, Handle<String>::cast(name)->ToCString().get()) |
| 1120 : GetCodeWithFlags(flags, NULL); | 1114 : GetCodeWithFlags(flags, NULL); |
| 1121 } | 1115 } |
| 1122 | 1116 |
| 1123 | 1117 |
| 1124 void StubCompiler::LookupPostInterceptor(Handle<JSObject> holder, | 1118 void StubCompiler::LookupPostInterceptor(Handle<JSObject> holder, |
| 1125 Handle<Name> name, | 1119 Handle<Name> name, |
| 1126 LookupResult* lookup) { | 1120 LookupResult* lookup) { |
| 1127 holder->LocalLookupRealNamedProperty(*name, lookup); | 1121 holder->LocalLookupRealNamedProperty(*name, lookup); |
| 1128 if (lookup->IsFound()) return; | 1122 if (lookup->IsFound()) return; |
| 1129 if (holder->GetPrototype()->IsNull()) return; | 1123 if (holder->GetPrototype()->IsNull()) return; |
| 1130 holder->GetPrototype()->Lookup(*name, lookup); | 1124 holder->GetPrototype()->Lookup(*name, lookup); |
| 1131 } | 1125 } |
| 1132 | 1126 |
| 1133 | 1127 |
| 1134 #define __ ACCESS_MASM(masm()) | 1128 #define __ ACCESS_MASM(masm()) |
| 1135 | 1129 |
| 1136 | 1130 |
| 1131 CallKind CallStubCompiler::call_kind() { |
| 1132 return CallICBase::Contextual::decode(extra_state()) |
| 1133 ? CALL_AS_FUNCTION |
| 1134 : CALL_AS_METHOD; |
| 1135 } |
| 1136 |
| 1137 |
| 1138 void CallStubCompiler::HandlerFrontendFooter(Label* miss) { |
| 1139 __ bind(miss); |
| 1140 GenerateMissBranch(); |
| 1141 } |
| 1142 |
| 1143 |
| 1144 void CallStubCompiler::GenerateJumpFunctionIgnoreReceiver( |
| 1145 Handle<JSFunction> function) { |
| 1146 ParameterCount expected(function); |
| 1147 __ InvokeFunction(function, expected, arguments(), |
| 1148 JUMP_FUNCTION, NullCallWrapper(), call_kind()); |
| 1149 } |
| 1150 |
| 1151 |
| 1152 void CallStubCompiler::GenerateJumpFunction(Handle<Object> object, |
| 1153 Handle<JSFunction> function) { |
| 1154 PatchGlobalProxy(object); |
| 1155 GenerateJumpFunctionIgnoreReceiver(function); |
| 1156 } |
| 1157 |
| 1158 |
| 1159 void CallStubCompiler::GenerateJumpFunction(Handle<Object> object, |
| 1160 Register actual_closure, |
| 1161 Handle<JSFunction> function) { |
| 1162 PatchGlobalProxy(object); |
| 1163 ParameterCount expected(function); |
| 1164 __ InvokeFunction(actual_closure, expected, arguments(), |
| 1165 JUMP_FUNCTION, NullCallWrapper(), call_kind()); |
| 1166 } |
| 1167 |
| 1168 |
| 1169 Handle<Code> CallStubCompiler::CompileCallConstant( |
| 1170 Handle<Object> object, |
| 1171 Handle<JSObject> holder, |
| 1172 Handle<Name> name, |
| 1173 CheckType check, |
| 1174 Handle<JSFunction> function) { |
| 1175 if (HasCustomCallGenerator(function)) { |
| 1176 Handle<Code> code = CompileCustomCall(object, holder, |
| 1177 Handle<Cell>::null(), |
| 1178 function, Handle<String>::cast(name), |
| 1179 Code::FAST); |
| 1180 // A null handle means bail out to the regular compiler code below. |
| 1181 if (!code.is_null()) return code; |
| 1182 } |
| 1183 |
| 1184 Label miss; |
| 1185 HandlerFrontendHeader(object, holder, name, check, &miss); |
| 1186 GenerateJumpFunction(object, function); |
| 1187 HandlerFrontendFooter(&miss); |
| 1188 |
| 1189 // Return the generated code. |
| 1190 return GetCode(function); |
| 1191 } |
| 1192 |
| 1193 |
| 1137 Register LoadStubCompiler::HandlerFrontendHeader( | 1194 Register LoadStubCompiler::HandlerFrontendHeader( |
| 1138 Handle<Object> object, | 1195 Handle<Type> type, |
| 1139 Register object_reg, | 1196 Register object_reg, |
| 1140 Handle<JSObject> holder, | 1197 Handle<JSObject> holder, |
| 1141 Handle<Name> name, | 1198 Handle<Name> name, |
| 1142 Label* miss) { | 1199 Label* miss) { |
| 1143 Handle<JSObject> receiver; | |
| 1144 PrototypeCheckType check_type = CHECK_ALL_MAPS; | 1200 PrototypeCheckType check_type = CHECK_ALL_MAPS; |
| 1145 int function_index = -1; | 1201 int function_index = -1; |
| 1146 if (object->IsJSObject()) { | 1202 if (type->Is(Type::String())) { |
| 1147 receiver = Handle<JSObject>::cast(object); | 1203 function_index = Context::STRING_FUNCTION_INDEX; |
| 1204 } else if (type->Is(Type::Symbol())) { |
| 1205 function_index = Context::SYMBOL_FUNCTION_INDEX; |
| 1206 } else if (type->Is(Type::Number())) { |
| 1207 function_index = Context::NUMBER_FUNCTION_INDEX; |
| 1208 } else if (type->Is(Type::Boolean())) { |
| 1209 // Booleans use the generic oddball map, so an additional check is needed to |
| 1210 // ensure the receiver is really a boolean. |
| 1211 GenerateBooleanCheck(object_reg, miss); |
| 1212 function_index = Context::BOOLEAN_FUNCTION_INDEX; |
| 1213 } else { |
| 1148 check_type = SKIP_RECEIVER; | 1214 check_type = SKIP_RECEIVER; |
| 1149 } else { | 1215 } |
| 1150 if (object->IsString()) { | |
| 1151 function_index = Context::STRING_FUNCTION_INDEX; | |
| 1152 } else if (object->IsSymbol()) { | |
| 1153 function_index = Context::SYMBOL_FUNCTION_INDEX; | |
| 1154 } else if (object->IsNumber()) { | |
| 1155 function_index = Context::NUMBER_FUNCTION_INDEX; | |
| 1156 } else { | |
| 1157 ASSERT(object->IsBoolean()); | |
| 1158 // Booleans use the generic oddball map, so an additional check is | |
| 1159 // needed to ensure the receiver is really a boolean. | |
| 1160 GenerateBooleanCheck(object_reg, miss); | |
| 1161 function_index = Context::BOOLEAN_FUNCTION_INDEX; | |
| 1162 } | |
| 1163 | 1216 |
| 1217 if (check_type == CHECK_ALL_MAPS) { |
| 1164 GenerateDirectLoadGlobalFunctionPrototype( | 1218 GenerateDirectLoadGlobalFunctionPrototype( |
| 1165 masm(), function_index, scratch1(), miss); | 1219 masm(), function_index, scratch1(), miss); |
| 1166 receiver = handle(JSObject::cast(object->GetPrototype(isolate()))); | 1220 Object* function = isolate()->native_context()->get(function_index); |
| 1221 Object* prototype = JSFunction::cast(function)->instance_prototype(); |
| 1222 type = IC::CurrentTypeOf(handle(prototype, isolate()), isolate()); |
| 1167 object_reg = scratch1(); | 1223 object_reg = scratch1(); |
| 1168 } | 1224 } |
| 1169 | 1225 |
| 1170 // Check that the maps starting from the prototype haven't changed. | 1226 // Check that the maps starting from the prototype haven't changed. |
| 1171 return CheckPrototypes(receiver, object_reg, holder, | 1227 return CheckPrototypes( |
| 1172 scratch1(), scratch2(), scratch3(), | 1228 type, object_reg, holder, scratch1(), scratch2(), scratch3(), |
| 1173 name, miss, check_type); | 1229 name, miss, check_type); |
| 1174 } | 1230 } |
| 1175 | 1231 |
| 1176 | 1232 |
| 1177 // HandlerFrontend for store uses the name register. It has to be restored | 1233 // HandlerFrontend for store uses the name register. It has to be restored |
| 1178 // before a miss. | 1234 // before a miss. |
| 1179 Register StoreStubCompiler::HandlerFrontendHeader( | 1235 Register StoreStubCompiler::HandlerFrontendHeader( |
| 1180 Handle<Object> object, | 1236 Handle<Type> type, |
| 1181 Register object_reg, | 1237 Register object_reg, |
| 1182 Handle<JSObject> holder, | 1238 Handle<JSObject> holder, |
| 1183 Handle<Name> name, | 1239 Handle<Name> name, |
| 1184 Label* miss) { | 1240 Label* miss) { |
| 1185 return CheckPrototypes(Handle<JSObject>::cast(object), object_reg, holder, | 1241 return CheckPrototypes(type, object_reg, holder, this->name(), |
| 1186 this->name(), scratch1(), scratch2(), | 1242 scratch1(), scratch2(), name, miss, SKIP_RECEIVER); |
| 1187 name, miss, SKIP_RECEIVER); | |
| 1188 } | 1243 } |
| 1189 | 1244 |
| 1190 | 1245 |
| 1191 bool BaseLoadStoreStubCompiler::IncludesNumberType(TypeHandleList* types) { | 1246 bool BaseLoadStoreStubCompiler::IncludesNumberType(TypeHandleList* types) { |
| 1192 for (int i = 0; i < types->length(); ++i) { | 1247 for (int i = 0; i < types->length(); ++i) { |
| 1193 if (types->at(i)->Is(Type::Number())) return true; | 1248 if (types->at(i)->Is(Type::Number())) return true; |
| 1194 } | 1249 } |
| 1195 return false; | 1250 return false; |
| 1196 } | 1251 } |
| 1197 | 1252 |
| 1198 | 1253 |
| 1199 Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<Object> object, | 1254 Register BaseLoadStoreStubCompiler::HandlerFrontend(Handle<Type> type, |
| 1200 Register object_reg, | 1255 Register object_reg, |
| 1201 Handle<JSObject> holder, | 1256 Handle<JSObject> holder, |
| 1202 Handle<Name> name) { | 1257 Handle<Name> name) { |
| 1203 Label miss; | 1258 Label miss; |
| 1204 | 1259 |
| 1205 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); | 1260 Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss); |
| 1206 | 1261 |
| 1207 HandlerFrontendFooter(name, &miss); | 1262 HandlerFrontendFooter(name, &miss); |
| 1208 | 1263 |
| 1209 return reg; | 1264 return reg; |
| 1210 } | 1265 } |
| 1211 | 1266 |
| 1212 | 1267 |
| 1213 void LoadStubCompiler::NonexistentHandlerFrontend( | 1268 void LoadStubCompiler::NonexistentHandlerFrontend(Handle<Type> type, |
| 1214 Handle<Object> object, | 1269 Handle<JSObject> last, |
| 1215 Handle<JSObject> last, | 1270 Handle<Name> name) { |
| 1216 Handle<Name> name, | |
| 1217 Handle<JSGlobalObject> global) { | |
| 1218 Label miss; | 1271 Label miss; |
| 1219 | 1272 |
| 1220 Register holder = HandlerFrontendHeader( | 1273 Register holder; |
| 1221 object, receiver(), last, name, &miss); | 1274 Handle<Map> last_map; |
| 1275 if (last.is_null()) { |
| 1276 holder = receiver(); |
| 1277 last_map = IC::TypeToMap(*type, isolate()); |
| 1278 // If |type| has null as its prototype, |last| is Handle<JSObject>::null(). |
| 1279 ASSERT(last_map->prototype() == isolate()->heap()->null_value()); |
| 1280 } else { |
| 1281 holder = HandlerFrontendHeader(type, receiver(), last, name, &miss); |
| 1282 last_map = handle(last->map()); |
| 1283 } |
| 1222 | 1284 |
| 1223 if (!last->HasFastProperties() && | 1285 if (last_map->is_dictionary_map() && |
| 1224 !last->IsJSGlobalObject() && | 1286 !last_map->IsJSGlobalObjectMap() && |
| 1225 !last->IsJSGlobalProxy()) { | 1287 !last_map->IsJSGlobalProxyMap()) { |
| 1226 if (!name->IsUniqueName()) { | 1288 if (!name->IsUniqueName()) { |
| 1227 ASSERT(name->IsString()); | 1289 ASSERT(name->IsString()); |
| 1228 name = factory()->InternalizeString(Handle<String>::cast(name)); | 1290 name = factory()->InternalizeString(Handle<String>::cast(name)); |
| 1229 } | 1291 } |
| 1230 ASSERT(last->property_dictionary()->FindEntry(*name) == | 1292 ASSERT(last.is_null() || |
| 1231 NameDictionary::kNotFound); | 1293 last->property_dictionary()->FindEntry(*name) == |
| 1294 NameDictionary::kNotFound); |
| 1232 GenerateDictionaryNegativeLookup(masm(), &miss, holder, name, | 1295 GenerateDictionaryNegativeLookup(masm(), &miss, holder, name, |
| 1233 scratch2(), scratch3()); | 1296 scratch2(), scratch3()); |
| 1234 } | 1297 } |
| 1235 | 1298 |
| 1236 // If the last object in the prototype chain is a global object, | 1299 // If the last object in the prototype chain is a global object, |
| 1237 // check that the global property cell is empty. | 1300 // check that the global property cell is empty. |
| 1238 if (!global.is_null()) { | 1301 if (last_map->IsJSGlobalObjectMap()) { |
| 1302 Handle<JSGlobalObject> global = last.is_null() |
| 1303 ? Handle<JSGlobalObject>::cast(type->AsConstant()) |
| 1304 : Handle<JSGlobalObject>::cast(last); |
| 1239 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); | 1305 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); |
| 1240 } | 1306 } |
| 1241 | 1307 |
| 1242 HandlerFrontendFooter(name, &miss); | 1308 HandlerFrontendFooter(name, &miss); |
| 1243 } | 1309 } |
| 1244 | 1310 |
| 1245 | 1311 |
| 1246 Handle<Code> LoadStubCompiler::CompileLoadField( | 1312 Handle<Code> LoadStubCompiler::CompileLoadField( |
| 1247 Handle<Object> object, | 1313 Handle<Type> type, |
| 1248 Handle<JSObject> holder, | 1314 Handle<JSObject> holder, |
| 1249 Handle<Name> name, | 1315 Handle<Name> name, |
| 1250 PropertyIndex field, | 1316 PropertyIndex field, |
| 1251 Representation representation) { | 1317 Representation representation) { |
| 1252 Label miss; | 1318 Label miss; |
| 1253 | 1319 |
| 1254 Register reg = HandlerFrontendHeader(object, receiver(), holder, name, &miss); | 1320 Register reg = HandlerFrontendHeader(type, receiver(), holder, name, &miss); |
| 1255 | 1321 |
| 1256 GenerateLoadField(reg, holder, field, representation); | 1322 GenerateLoadField(reg, holder, field, representation); |
| 1257 | 1323 |
| 1258 __ bind(&miss); | 1324 __ bind(&miss); |
| 1259 TailCallBuiltin(masm(), MissBuiltin(kind())); | 1325 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 1260 | 1326 |
| 1261 // Return the generated code. | 1327 // Return the generated code. |
| 1262 return GetCode(kind(), Code::FAST, name); | 1328 return GetCode(kind(), Code::FAST, name); |
| 1263 } | 1329 } |
| 1264 | 1330 |
| 1265 | 1331 |
| 1266 Handle<Code> LoadStubCompiler::CompileLoadConstant( | 1332 Handle<Code> LoadStubCompiler::CompileLoadConstant( |
| 1267 Handle<Object> object, | 1333 Handle<Type> type, |
| 1268 Handle<JSObject> holder, | 1334 Handle<JSObject> holder, |
| 1269 Handle<Name> name, | 1335 Handle<Name> name, |
| 1270 Handle<Object> value) { | 1336 Handle<Object> value) { |
| 1271 HandlerFrontend(object, receiver(), holder, name); | 1337 HandlerFrontend(type, receiver(), holder, name); |
| 1272 GenerateLoadConstant(value); | 1338 GenerateLoadConstant(value); |
| 1273 | 1339 |
| 1274 // Return the generated code. | 1340 // Return the generated code. |
| 1275 return GetCode(kind(), Code::FAST, name); | 1341 return GetCode(kind(), Code::FAST, name); |
| 1276 } | 1342 } |
| 1277 | 1343 |
| 1278 | 1344 |
| 1279 Handle<Code> LoadStubCompiler::CompileLoadCallback( | 1345 Handle<Code> LoadStubCompiler::CompileLoadCallback( |
| 1280 Handle<Object> object, | 1346 Handle<Type> type, |
| 1281 Handle<JSObject> holder, | 1347 Handle<JSObject> holder, |
| 1282 Handle<Name> name, | 1348 Handle<Name> name, |
| 1283 Handle<ExecutableAccessorInfo> callback) { | 1349 Handle<ExecutableAccessorInfo> callback) { |
| 1284 Register reg = CallbackHandlerFrontend( | 1350 Register reg = CallbackHandlerFrontend( |
| 1285 object, receiver(), holder, name, callback); | 1351 type, receiver(), holder, name, callback); |
| 1286 GenerateLoadCallback(reg, callback); | 1352 GenerateLoadCallback(reg, callback); |
| 1287 | 1353 |
| 1288 // Return the generated code. | 1354 // Return the generated code. |
| 1289 return GetCode(kind(), Code::FAST, name); | 1355 return GetCode(kind(), Code::FAST, name); |
| 1290 } | 1356 } |
| 1291 | 1357 |
| 1292 | 1358 |
| 1293 Handle<Code> LoadStubCompiler::CompileLoadCallback( | 1359 Handle<Code> LoadStubCompiler::CompileLoadCallback( |
| 1294 Handle<Object> object, | 1360 Handle<Type> type, |
| 1295 Handle<JSObject> holder, | 1361 Handle<JSObject> holder, |
| 1296 Handle<Name> name, | 1362 Handle<Name> name, |
| 1297 const CallOptimization& call_optimization) { | 1363 const CallOptimization& call_optimization) { |
| 1298 ASSERT(call_optimization.is_simple_api_call()); | 1364 ASSERT(call_optimization.is_simple_api_call()); |
| 1299 Handle<JSFunction> callback = call_optimization.constant_function(); | 1365 Handle<JSFunction> callback = call_optimization.constant_function(); |
| 1300 CallbackHandlerFrontend(object, receiver(), holder, name, callback); | 1366 CallbackHandlerFrontend(type, receiver(), holder, name, callback); |
| 1301 GenerateLoadCallback(call_optimization); | 1367 GenerateLoadCallback(call_optimization); |
| 1302 | 1368 |
| 1303 // Return the generated code. | 1369 // Return the generated code. |
| 1304 return GetCode(kind(), Code::FAST, name); | 1370 return GetCode(kind(), Code::FAST, name); |
| 1305 } | 1371 } |
| 1306 | 1372 |
| 1307 | 1373 |
| 1308 Handle<Code> LoadStubCompiler::CompileLoadInterceptor( | 1374 Handle<Code> LoadStubCompiler::CompileLoadInterceptor( |
| 1309 Handle<Object> object, | 1375 Handle<Type> type, |
| 1310 Handle<JSObject> holder, | 1376 Handle<JSObject> holder, |
| 1311 Handle<Name> name) { | 1377 Handle<Name> name) { |
| 1312 LookupResult lookup(isolate()); | 1378 LookupResult lookup(isolate()); |
| 1313 LookupPostInterceptor(holder, name, &lookup); | 1379 LookupPostInterceptor(holder, name, &lookup); |
| 1314 | 1380 |
| 1315 Register reg = HandlerFrontend(object, receiver(), holder, name); | 1381 Register reg = HandlerFrontend(type, receiver(), holder, name); |
| 1316 // TODO(368): Compile in the whole chain: all the interceptors in | 1382 // TODO(368): Compile in the whole chain: all the interceptors in |
| 1317 // prototypes and ultimate answer. | 1383 // prototypes and ultimate answer. |
| 1318 GenerateLoadInterceptor(reg, object, holder, &lookup, name); | 1384 GenerateLoadInterceptor(reg, type, holder, &lookup, name); |
| 1319 | 1385 |
| 1320 // Return the generated code. | 1386 // Return the generated code. |
| 1321 return GetCode(kind(), Code::FAST, name); | 1387 return GetCode(kind(), Code::FAST, name); |
| 1322 } | 1388 } |
| 1323 | 1389 |
| 1324 | 1390 |
| 1325 void LoadStubCompiler::GenerateLoadPostInterceptor( | 1391 void LoadStubCompiler::GenerateLoadPostInterceptor( |
| 1326 Register interceptor_reg, | 1392 Register interceptor_reg, |
| 1327 Handle<JSObject> interceptor_holder, | 1393 Handle<JSObject> interceptor_holder, |
| 1328 Handle<Name> name, | 1394 Handle<Name> name, |
| 1329 LookupResult* lookup) { | 1395 LookupResult* lookup) { |
| 1330 Handle<JSObject> holder(lookup->holder()); | 1396 Handle<JSObject> holder(lookup->holder()); |
| 1331 if (lookup->IsField()) { | 1397 if (lookup->IsField()) { |
| 1332 PropertyIndex field = lookup->GetFieldIndex(); | 1398 PropertyIndex field = lookup->GetFieldIndex(); |
| 1333 if (interceptor_holder.is_identical_to(holder)) { | 1399 if (interceptor_holder.is_identical_to(holder)) { |
| 1334 GenerateLoadField( | 1400 GenerateLoadField( |
| 1335 interceptor_reg, holder, field, lookup->representation()); | 1401 interceptor_reg, holder, field, lookup->representation()); |
| 1336 } else { | 1402 } else { |
| 1337 // We found FIELD property in prototype chain of interceptor's holder. | 1403 // We found FIELD property in prototype chain of interceptor's holder. |
| 1338 // Retrieve a field from field's holder. | 1404 // Retrieve a field from field's holder. |
| 1339 Register reg = HandlerFrontend( | 1405 Register reg = HandlerFrontend( |
| 1340 interceptor_holder, interceptor_reg, holder, name); | 1406 IC::CurrentTypeOf(interceptor_holder, isolate()), |
| 1407 interceptor_reg, holder, name); |
| 1341 GenerateLoadField( | 1408 GenerateLoadField( |
| 1342 reg, holder, field, lookup->representation()); | 1409 reg, holder, field, lookup->representation()); |
| 1343 } | 1410 } |
| 1344 } else { | 1411 } else { |
| 1345 // We found CALLBACKS property in prototype chain of interceptor's | 1412 // We found CALLBACKS property in prototype chain of interceptor's |
| 1346 // holder. | 1413 // holder. |
| 1347 ASSERT(lookup->type() == CALLBACKS); | 1414 ASSERT(lookup->type() == CALLBACKS); |
| 1348 Handle<ExecutableAccessorInfo> callback( | 1415 Handle<ExecutableAccessorInfo> callback( |
| 1349 ExecutableAccessorInfo::cast(lookup->GetCallbackObject())); | 1416 ExecutableAccessorInfo::cast(lookup->GetCallbackObject())); |
| 1350 ASSERT(callback->getter() != NULL); | 1417 ASSERT(callback->getter() != NULL); |
| 1351 | 1418 |
| 1352 Register reg = CallbackHandlerFrontend( | 1419 Register reg = CallbackHandlerFrontend( |
| 1353 interceptor_holder, interceptor_reg, holder, name, callback); | 1420 IC::CurrentTypeOf(interceptor_holder, isolate()), |
| 1421 interceptor_reg, holder, name, callback); |
| 1354 GenerateLoadCallback(reg, callback); | 1422 GenerateLoadCallback(reg, callback); |
| 1355 } | 1423 } |
| 1356 } | 1424 } |
| 1357 | 1425 |
| 1358 | 1426 |
| 1359 Handle<Code> BaseLoadStoreStubCompiler::CompileMonomorphicIC( | 1427 Handle<Code> BaseLoadStoreStubCompiler::CompileMonomorphicIC( |
| 1360 Handle<Type> type, | 1428 Handle<Type> type, |
| 1361 Handle<Code> handler, | 1429 Handle<Code> handler, |
| 1362 Handle<Name> name) { | 1430 Handle<Name> name) { |
| 1363 TypeHandleList types(1); | 1431 TypeHandleList types(1); |
| 1364 CodeHandleList handlers(1); | 1432 CodeHandleList handlers(1); |
| 1365 types.Add(type); | 1433 types.Add(type); |
| 1366 handlers.Add(handler); | 1434 handlers.Add(handler); |
| 1367 Code::StubType stub_type = handler->type(); | 1435 Code::StubType stub_type = handler->type(); |
| 1368 return CompilePolymorphicIC(&types, &handlers, name, stub_type, PROPERTY); | 1436 return CompilePolymorphicIC(&types, &handlers, name, stub_type, PROPERTY); |
| 1369 } | 1437 } |
| 1370 | 1438 |
| 1371 | 1439 |
| 1372 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( | 1440 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( |
| 1373 Handle<Object> object, | 1441 Handle<Type> type, |
| 1374 Handle<JSObject> holder, | 1442 Handle<JSObject> holder, |
| 1375 Handle<Name> name, | 1443 Handle<Name> name, |
| 1376 Handle<JSFunction> getter) { | 1444 Handle<JSFunction> getter) { |
| 1377 HandlerFrontend(object, receiver(), holder, name); | 1445 HandlerFrontend(type, receiver(), holder, name); |
| 1378 GenerateLoadViaGetter(masm(), receiver(), getter); | 1446 GenerateLoadViaGetter(masm(), receiver(), getter); |
| 1379 | 1447 |
| 1380 // Return the generated code. | 1448 // Return the generated code. |
| 1381 return GetCode(kind(), Code::FAST, name); | 1449 return GetCode(kind(), Code::FAST, name); |
| 1382 } | 1450 } |
| 1383 | 1451 |
| 1384 | 1452 |
| 1385 Handle<Code> StoreStubCompiler::CompileStoreTransition( | 1453 Handle<Code> StoreStubCompiler::CompileStoreTransition( |
| 1386 Handle<JSObject> object, | 1454 Handle<JSObject> object, |
| 1387 LookupResult* lookup, | 1455 LookupResult* lookup, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1399 if (lookup->holder() != *object) { | 1467 if (lookup->holder() != *object) { |
| 1400 holder = Handle<JSObject>(lookup->holder()); | 1468 holder = Handle<JSObject>(lookup->holder()); |
| 1401 } else { | 1469 } else { |
| 1402 // Find the top object. | 1470 // Find the top object. |
| 1403 holder = object; | 1471 holder = object; |
| 1404 do { | 1472 do { |
| 1405 holder = Handle<JSObject>(JSObject::cast(holder->GetPrototype())); | 1473 holder = Handle<JSObject>(JSObject::cast(holder->GetPrototype())); |
| 1406 } while (holder->GetPrototype()->IsJSObject()); | 1474 } while (holder->GetPrototype()->IsJSObject()); |
| 1407 } | 1475 } |
| 1408 | 1476 |
| 1409 Register holder_reg = | 1477 Register holder_reg = HandlerFrontendHeader( |
| 1410 HandlerFrontendHeader(object, receiver(), holder, name, &miss); | 1478 IC::CurrentTypeOf(object, isolate()), receiver(), holder, name, &miss); |
| 1411 | 1479 |
| 1412 // If no property was found, and the holder (the last object in the | 1480 // If no property was found, and the holder (the last object in the |
| 1413 // prototype chain) is in slow mode, we need to do a negative lookup on the | 1481 // prototype chain) is in slow mode, we need to do a negative lookup on the |
| 1414 // holder. | 1482 // holder. |
| 1415 if (lookup->holder() == *object) { | 1483 if (lookup->holder() == *object) { |
| 1416 GenerateNegativeHolderLookup(masm(), holder, holder_reg, name, &miss); | 1484 GenerateNegativeHolderLookup(masm(), holder, holder_reg, name, &miss); |
| 1417 } | 1485 } |
| 1418 } | 1486 } |
| 1419 | 1487 |
| 1420 GenerateStoreTransition(masm(), | 1488 GenerateStoreTransition(masm(), |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1437 // Return the generated code. | 1505 // Return the generated code. |
| 1438 return GetCode(kind(), Code::FAST, name); | 1506 return GetCode(kind(), Code::FAST, name); |
| 1439 } | 1507 } |
| 1440 | 1508 |
| 1441 | 1509 |
| 1442 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, | 1510 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, |
| 1443 LookupResult* lookup, | 1511 LookupResult* lookup, |
| 1444 Handle<Name> name) { | 1512 Handle<Name> name) { |
| 1445 Label miss; | 1513 Label miss; |
| 1446 | 1514 |
| 1447 HandlerFrontendHeader(object, receiver(), object, name, &miss); | 1515 HandlerFrontendHeader(IC::CurrentTypeOf(object, isolate()), |
| 1516 receiver(), object, name, &miss); |
| 1448 | 1517 |
| 1449 // Generate store field code. | 1518 // Generate store field code. |
| 1450 GenerateStoreField(masm(), | 1519 GenerateStoreField(masm(), |
| 1451 object, | 1520 object, |
| 1452 lookup, | 1521 lookup, |
| 1453 receiver(), this->name(), value(), scratch1(), scratch2(), | 1522 receiver(), this->name(), value(), scratch1(), scratch2(), |
| 1454 &miss); | 1523 &miss); |
| 1455 | 1524 |
| 1456 // Handle store cache miss. | 1525 // Handle store cache miss. |
| 1457 __ bind(&miss); | 1526 __ bind(&miss); |
| 1458 TailCallBuiltin(masm(), MissBuiltin(kind())); | 1527 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 1459 | 1528 |
| 1460 // Return the generated code. | 1529 // Return the generated code. |
| 1461 return GetCode(kind(), Code::FAST, name); | 1530 return GetCode(kind(), Code::FAST, name); |
| 1462 } | 1531 } |
| 1463 | 1532 |
| 1464 | 1533 |
| 1465 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( | 1534 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( |
| 1466 Handle<JSObject> object, | 1535 Handle<JSObject> object, |
| 1467 Handle<JSObject> holder, | 1536 Handle<JSObject> holder, |
| 1468 Handle<Name> name, | 1537 Handle<Name> name, |
| 1469 Handle<JSFunction> setter) { | 1538 Handle<JSFunction> setter) { |
| 1470 HandlerFrontend(object, receiver(), holder, name); | 1539 HandlerFrontend(IC::CurrentTypeOf(object, isolate()), |
| 1540 receiver(), holder, name); |
| 1471 GenerateStoreViaSetter(masm(), setter); | 1541 GenerateStoreViaSetter(masm(), setter); |
| 1472 | 1542 |
| 1473 return GetCode(kind(), Code::FAST, name); | 1543 return GetCode(kind(), Code::FAST, name); |
| 1474 } | 1544 } |
| 1475 | 1545 |
| 1476 | 1546 |
| 1477 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( | 1547 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( |
| 1478 Handle<Map> receiver_map) { | 1548 Handle<Map> receiver_map) { |
| 1479 ElementsKind elements_kind = receiver_map->elements_kind(); | 1549 ElementsKind elements_kind = receiver_map->elements_kind(); |
| 1480 if (receiver_map->has_fast_elements() || | 1550 if (receiver_map->has_fast_elements() || |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1500 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement( | 1570 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement( |
| 1501 Handle<Map> receiver_map) { | 1571 Handle<Map> receiver_map) { |
| 1502 ElementsKind elements_kind = receiver_map->elements_kind(); | 1572 ElementsKind elements_kind = receiver_map->elements_kind(); |
| 1503 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; | 1573 bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; |
| 1504 Handle<Code> stub; | 1574 Handle<Code> stub; |
| 1505 if (receiver_map->has_fast_elements() || | 1575 if (receiver_map->has_fast_elements() || |
| 1506 receiver_map->has_external_array_elements()) { | 1576 receiver_map->has_external_array_elements()) { |
| 1507 stub = KeyedStoreFastElementStub( | 1577 stub = KeyedStoreFastElementStub( |
| 1508 is_jsarray, | 1578 is_jsarray, |
| 1509 elements_kind, | 1579 elements_kind, |
| 1510 store_mode_).GetCode(isolate()); | 1580 store_mode()).GetCode(isolate()); |
| 1511 } else { | 1581 } else { |
| 1512 stub = KeyedStoreElementStub(is_jsarray, | 1582 stub = KeyedStoreElementStub(is_jsarray, |
| 1513 elements_kind, | 1583 elements_kind, |
| 1514 store_mode_).GetCode(isolate()); | 1584 store_mode()).GetCode(isolate()); |
| 1515 } | 1585 } |
| 1516 | 1586 |
| 1517 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK); | 1587 __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK); |
| 1518 | 1588 |
| 1519 TailCallBuiltin(masm(), Builtins::kKeyedStoreIC_Miss); | 1589 TailCallBuiltin(masm(), Builtins::kKeyedStoreIC_Miss); |
| 1520 | 1590 |
| 1521 // Return the generated code. | 1591 // Return the generated code. |
| 1522 return GetICCode(kind(), Code::NORMAL, factory()->empty_string()); | 1592 return GetICCode(kind(), Code::NORMAL, factory()->empty_string()); |
| 1523 } | 1593 } |
| 1524 | 1594 |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1630 // Tracking to do a better job of ensuring the data types are what they need | 1700 // Tracking to do a better job of ensuring the data types are what they need |
| 1631 // to be. Not all the elements are in place yet, pessimistic elements | 1701 // to be. Not all the elements are in place yet, pessimistic elements |
| 1632 // transitions are still important for performance. | 1702 // transitions are still important for performance. |
| 1633 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; | 1703 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; |
| 1634 ElementsKind elements_kind = receiver_map->elements_kind(); | 1704 ElementsKind elements_kind = receiver_map->elements_kind(); |
| 1635 if (!transitioned_map.is_null()) { | 1705 if (!transitioned_map.is_null()) { |
| 1636 cached_stub = ElementsTransitionAndStoreStub( | 1706 cached_stub = ElementsTransitionAndStoreStub( |
| 1637 elements_kind, | 1707 elements_kind, |
| 1638 transitioned_map->elements_kind(), | 1708 transitioned_map->elements_kind(), |
| 1639 is_js_array, | 1709 is_js_array, |
| 1640 store_mode_).GetCode(isolate()); | 1710 store_mode()).GetCode(isolate()); |
| 1641 } else { | 1711 } else { |
| 1642 if (receiver_map->has_fast_elements() || | 1712 if (receiver_map->has_fast_elements() || |
| 1643 receiver_map->has_external_array_elements()) { | 1713 receiver_map->has_external_array_elements()) { |
| 1644 cached_stub = KeyedStoreFastElementStub( | 1714 cached_stub = KeyedStoreFastElementStub( |
| 1645 is_js_array, | 1715 is_js_array, |
| 1646 elements_kind, | 1716 elements_kind, |
| 1647 store_mode_).GetCode(isolate()); | 1717 store_mode()).GetCode(isolate()); |
| 1648 } else { | 1718 } else { |
| 1649 cached_stub = KeyedStoreElementStub( | 1719 cached_stub = KeyedStoreElementStub( |
| 1650 is_js_array, | 1720 is_js_array, |
| 1651 elements_kind, | 1721 elements_kind, |
| 1652 store_mode_).GetCode(isolate()); | 1722 store_mode()).GetCode(isolate()); |
| 1653 } | 1723 } |
| 1654 } | 1724 } |
| 1655 ASSERT(!cached_stub.is_null()); | 1725 ASSERT(!cached_stub.is_null()); |
| 1656 handlers.Add(cached_stub); | 1726 handlers.Add(cached_stub); |
| 1657 transitioned_maps.Add(transitioned_map); | 1727 transitioned_maps.Add(transitioned_map); |
| 1658 } | 1728 } |
| 1659 Handle<Code> code = | 1729 Handle<Code> code = |
| 1660 CompileStorePolymorphic(receiver_maps, &handlers, &transitioned_maps); | 1730 CompileStorePolymorphic(receiver_maps, &handlers, &transitioned_maps); |
| 1661 isolate()->counters()->keyed_store_polymorphic_stubs()->Increment(); | 1731 isolate()->counters()->keyed_store_polymorphic_stubs()->Increment(); |
| 1662 PROFILE(isolate(), | 1732 PROFILE(isolate(), |
| 1663 CodeCreateEvent(Logger::KEYED_STORE_POLYMORPHIC_IC_TAG, *code, 0)); | 1733 CodeCreateEvent(Logger::KEYED_STORE_POLYMORPHIC_IC_TAG, *code, 0)); |
| 1664 return code; | 1734 return code; |
| 1665 } | 1735 } |
| 1666 | 1736 |
| 1667 | 1737 |
| 1668 void KeyedStoreStubCompiler::GenerateStoreDictionaryElement( | 1738 void KeyedStoreStubCompiler::GenerateStoreDictionaryElement( |
| 1669 MacroAssembler* masm) { | 1739 MacroAssembler* masm) { |
| 1670 KeyedStoreIC::GenerateSlow(masm); | 1740 KeyedStoreIC::GenerateSlow(masm); |
| 1671 } | 1741 } |
| 1672 | 1742 |
| 1673 | 1743 |
| 1674 CallStubCompiler::CallStubCompiler(Isolate* isolate, | 1744 CallStubCompiler::CallStubCompiler(Isolate* isolate, |
| 1675 int argc, | 1745 int argc, |
| 1676 Code::Kind kind, | 1746 Code::Kind kind, |
| 1677 Code::ExtraICState extra_state, | 1747 ExtraICState extra_state, |
| 1678 InlineCacheHolderFlag cache_holder) | 1748 InlineCacheHolderFlag cache_holder) |
| 1679 : StubCompiler(isolate), | 1749 : StubCompiler(isolate, extra_state), |
| 1680 arguments_(argc), | 1750 arguments_(argc), |
| 1681 kind_(kind), | 1751 kind_(kind), |
| 1682 extra_state_(extra_state), | |
| 1683 cache_holder_(cache_holder) { | 1752 cache_holder_(cache_holder) { |
| 1684 } | 1753 } |
| 1685 | 1754 |
| 1686 | 1755 |
| 1687 bool CallStubCompiler::HasCustomCallGenerator(Handle<JSFunction> function) { | 1756 bool CallStubCompiler::HasCustomCallGenerator(Handle<JSFunction> function) { |
| 1688 if (function->shared()->HasBuiltinFunctionId()) { | 1757 if (function->shared()->HasBuiltinFunctionId()) { |
| 1689 BuiltinFunctionId id = function->shared()->builtin_function_id(); | 1758 BuiltinFunctionId id = function->shared()->builtin_function_id(); |
| 1690 #define CALL_GENERATOR_CASE(name) if (id == k##name) return true; | 1759 #define CALL_GENERATOR_CASE(name) if (id == k##name) return true; |
| 1691 CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE) | 1760 CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE) |
| 1692 #undef CALL_GENERATOR_CASE | 1761 #undef CALL_GENERATOR_CASE |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1740 cell, | 1809 cell, |
| 1741 function, | 1810 function, |
| 1742 fname); | 1811 fname); |
| 1743 } | 1812 } |
| 1744 | 1813 |
| 1745 | 1814 |
| 1746 Handle<Code> CallStubCompiler::GetCode(Code::StubType type, | 1815 Handle<Code> CallStubCompiler::GetCode(Code::StubType type, |
| 1747 Handle<Name> name) { | 1816 Handle<Name> name) { |
| 1748 int argc = arguments_.immediate(); | 1817 int argc = arguments_.immediate(); |
| 1749 Code::Flags flags = Code::ComputeMonomorphicFlags( | 1818 Code::Flags flags = Code::ComputeMonomorphicFlags( |
| 1750 kind_, extra_state_, cache_holder_, type, argc); | 1819 kind_, extra_state(), cache_holder_, type, argc); |
| 1751 return GetCodeWithFlags(flags, name); | 1820 return GetCodeWithFlags(flags, name); |
| 1752 } | 1821 } |
| 1753 | 1822 |
| 1754 | 1823 |
| 1755 Handle<Code> CallStubCompiler::GetCode(Handle<JSFunction> function) { | 1824 Handle<Code> CallStubCompiler::GetCode(Handle<JSFunction> function) { |
| 1756 Handle<String> function_name; | 1825 Handle<String> function_name; |
| 1757 if (function->shared()->name()->IsString()) { | 1826 if (function->shared()->name()->IsString()) { |
| 1758 function_name = Handle<String>(String::cast(function->shared()->name())); | 1827 function_name = Handle<String>(String::cast(function->shared()->name())); |
| 1759 } | 1828 } |
| 1760 return GetCode(Code::FAST, function_name); | 1829 return GetCode(Code::FAST, function_name); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1828 Handle<FunctionTemplateInfo>( | 1897 Handle<FunctionTemplateInfo>( |
| 1829 FunctionTemplateInfo::cast(signature->receiver())); | 1898 FunctionTemplateInfo::cast(signature->receiver())); |
| 1830 } | 1899 } |
| 1831 } | 1900 } |
| 1832 | 1901 |
| 1833 is_simple_api_call_ = true; | 1902 is_simple_api_call_ = true; |
| 1834 } | 1903 } |
| 1835 | 1904 |
| 1836 | 1905 |
| 1837 } } // namespace v8::internal | 1906 } } // namespace v8::internal |
| OLD | NEW |