OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 return Set(name, receiver->map(), Code::cast(code)); | 165 return Set(name, receiver->map(), Code::cast(code)); |
166 } | 166 } |
167 | 167 |
168 | 168 |
169 Object* StubCache::ComputeLoadNormal(String* name, JSObject* receiver) { | 169 Object* StubCache::ComputeLoadNormal(String* name, JSObject* receiver) { |
170 Code* code = Builtins::builtin(Builtins::LoadIC_Normal); | 170 Code* code = Builtins::builtin(Builtins::LoadIC_Normal); |
171 return Set(name, receiver->map(), code); | 171 return Set(name, receiver->map(), code); |
172 } | 172 } |
173 | 173 |
174 | 174 |
| 175 Object* StubCache::ComputeLoadGlobal(String* name, |
| 176 JSGlobalObject* receiver, |
| 177 JSGlobalPropertyCell* cell) { |
| 178 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL); |
| 179 Object* code = receiver->map()->FindInCodeCache(name, flags); |
| 180 if (code->IsUndefined()) { |
| 181 LoadStubCompiler compiler; |
| 182 code = compiler.CompileLoadGlobal(receiver, cell, name); |
| 183 if (code->IsFailure()) return code; |
| 184 LOG(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); |
| 185 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); |
| 186 if (result->IsFailure()) return code; |
| 187 } |
| 188 return Set(name, receiver->map(), Code::cast(code)); |
| 189 } |
| 190 |
| 191 |
175 Object* StubCache::ComputeKeyedLoadField(String* name, | 192 Object* StubCache::ComputeKeyedLoadField(String* name, |
176 JSObject* receiver, | 193 JSObject* receiver, |
177 JSObject* holder, | 194 JSObject* holder, |
178 int field_index) { | 195 int field_index) { |
179 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, FIELD); | 196 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, FIELD); |
180 Object* code = receiver->map()->FindInCodeCache(name, flags); | 197 Object* code = receiver->map()->FindInCodeCache(name, flags); |
181 if (code->IsUndefined()) { | 198 if (code->IsUndefined()) { |
182 KeyedLoadStubCompiler compiler; | 199 KeyedLoadStubCompiler compiler; |
183 code = compiler.CompileLoadField(name, receiver, holder, field_index); | 200 code = compiler.CompileLoadField(name, receiver, holder, field_index); |
184 if (code->IsFailure()) return code; | 201 if (code->IsFailure()) return code; |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 code = compiler.CompileStoreField(receiver, field_index, transition, name); | 327 code = compiler.CompileStoreField(receiver, field_index, transition, name); |
311 if (code->IsFailure()) return code; | 328 if (code->IsFailure()) return code; |
312 LOG(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name)); | 329 LOG(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name)); |
313 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); | 330 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); |
314 if (result->IsFailure()) return result; | 331 if (result->IsFailure()) return result; |
315 } | 332 } |
316 return Set(name, receiver->map(), Code::cast(code)); | 333 return Set(name, receiver->map(), Code::cast(code)); |
317 } | 334 } |
318 | 335 |
319 | 336 |
| 337 Object* StubCache::ComputeStoreGlobal(String* name, |
| 338 JSGlobalObject* receiver, |
| 339 JSGlobalPropertyCell* cell) { |
| 340 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, NORMAL); |
| 341 Object* code = receiver->map()->FindInCodeCache(name, flags); |
| 342 if (code->IsUndefined()) { |
| 343 StoreStubCompiler compiler; |
| 344 code = compiler.CompileStoreGlobal(receiver, cell, name); |
| 345 if (code->IsFailure()) return code; |
| 346 LOG(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name)); |
| 347 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); |
| 348 if (result->IsFailure()) return code; |
| 349 } |
| 350 return Set(name, receiver->map(), Code::cast(code)); |
| 351 } |
| 352 |
| 353 |
320 Object* StubCache::ComputeStoreCallback(String* name, | 354 Object* StubCache::ComputeStoreCallback(String* name, |
321 JSObject* receiver, | 355 JSObject* receiver, |
322 AccessorInfo* callback) { | 356 AccessorInfo* callback) { |
323 ASSERT(v8::ToCData<Address>(callback->setter()) != 0); | 357 ASSERT(v8::ToCData<Address>(callback->setter()) != 0); |
324 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, CALLBACKS); | 358 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, CALLBACKS); |
325 Object* code = receiver->map()->FindInCodeCache(name, flags); | 359 Object* code = receiver->map()->FindInCodeCache(name, flags); |
326 if (code->IsUndefined()) { | 360 if (code->IsUndefined()) { |
327 StoreStubCompiler compiler; | 361 StoreStubCompiler compiler; |
328 code = compiler.CompileStoreCallback(receiver, callback, name); | 362 code = compiler.CompileStoreCallback(receiver, callback, name); |
329 if (code->IsFailure()) return code; | 363 if (code->IsFailure()) return code; |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 Object* StubCache::ComputeCallNormal(int argc, | 523 Object* StubCache::ComputeCallNormal(int argc, |
490 InLoopFlag in_loop, | 524 InLoopFlag in_loop, |
491 String* name, | 525 String* name, |
492 JSObject* receiver) { | 526 JSObject* receiver) { |
493 Object* code = ComputeCallNormal(argc, in_loop); | 527 Object* code = ComputeCallNormal(argc, in_loop); |
494 if (code->IsFailure()) return code; | 528 if (code->IsFailure()) return code; |
495 return Set(name, receiver->map(), Code::cast(code)); | 529 return Set(name, receiver->map(), Code::cast(code)); |
496 } | 530 } |
497 | 531 |
498 | 532 |
| 533 Object* StubCache::ComputeCallGlobal(int argc, |
| 534 InLoopFlag in_loop, |
| 535 String* name, |
| 536 JSGlobalObject* receiver, |
| 537 JSGlobalPropertyCell* cell, |
| 538 JSFunction* function) { |
| 539 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC, NORMAL); |
| 540 Object* code = receiver->map()->FindInCodeCache(name, flags); |
| 541 if (code->IsUndefined()) { |
| 542 // If the function hasn't been compiled yet, we cannot do it now |
| 543 // because it may cause GC. To avoid this issue, we return an |
| 544 // internal error which will make sure we do not update any |
| 545 // caches. |
| 546 if (!function->is_compiled()) return Failure::InternalError(); |
| 547 CallStubCompiler compiler(argc); |
| 548 code = compiler.CompileCallGlobal(receiver, cell, function, name); |
| 549 if (code->IsFailure()) return code; |
| 550 LOG(CodeCreateEvent(Logger::CALL_IC_TAG, Code::cast(code), name)); |
| 551 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); |
| 552 if (result->IsFailure()) return code; |
| 553 } |
| 554 return Set(name, receiver->map(), Code::cast(code)); |
| 555 } |
| 556 |
| 557 |
499 static Object* GetProbeValue(Code::Flags flags) { | 558 static Object* GetProbeValue(Code::Flags flags) { |
500 Dictionary* dictionary = Heap::non_monomorphic_cache(); | 559 Dictionary* dictionary = Heap::non_monomorphic_cache(); |
501 int entry = dictionary->FindNumberEntry(flags); | 560 int entry = dictionary->FindNumberEntry(flags); |
502 if (entry != -1) return dictionary->ValueAt(entry); | 561 if (entry != -1) return dictionary->ValueAt(entry); |
503 return Heap::undefined_value(); | 562 return Heap::undefined_value(); |
504 } | 563 } |
505 | 564 |
506 | 565 |
507 static Object* ProbeCache(Code::Flags flags) { | 566 static Object* ProbeCache(Code::Flags flags) { |
508 Object* probe = GetProbeValue(flags); | 567 Object* probe = GetProbeValue(flags); |
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
933 int argc = arguments_.immediate(); | 992 int argc = arguments_.immediate(); |
934 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC, | 993 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC, |
935 type, | 994 type, |
936 NOT_IN_LOOP, | 995 NOT_IN_LOOP, |
937 argc); | 996 argc); |
938 return GetCodeWithFlags(flags, name); | 997 return GetCodeWithFlags(flags, name); |
939 } | 998 } |
940 | 999 |
941 | 1000 |
942 } } // namespace v8::internal | 1001 } } // namespace v8::internal |
OLD | NEW |