Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/stub-cache.cc

Issue 112863002: Merge bleeding_edge 18021:18297 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/stub-cache.h ('k') | src/token.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/stub-cache.h ('k') | src/token.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698