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

Side by Side Diff: src/ic.cc

Issue 195983002: Reland "Pass a Code object to Assembler::(set_)target_address_at for use by ool constant pool." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix ia32 and x64 bug/ Created 6 years, 9 months 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/ic.h ('k') | src/ic-inl.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 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 ASSERT((TraceIC(type, name), true)) 120 ASSERT((TraceIC(type, name), true))
121 121
122 IC::IC(FrameDepth depth, Isolate* isolate) 122 IC::IC(FrameDepth depth, Isolate* isolate)
123 : isolate_(isolate), 123 : isolate_(isolate),
124 target_set_(false) { 124 target_set_(false) {
125 // To improve the performance of the (much used) IC code, we unfold a few 125 // To improve the performance of the (much used) IC code, we unfold a few
126 // levels of the stack frame iteration code. This yields a ~35% speedup when 126 // levels of the stack frame iteration code. This yields a ~35% speedup when
127 // running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic' flag. 127 // running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic' flag.
128 const Address entry = 128 const Address entry =
129 Isolate::c_entry_fp(isolate->thread_local_top()); 129 Isolate::c_entry_fp(isolate->thread_local_top());
130 Address constant_pool = NULL;
131 if (FLAG_enable_ool_constant_pool) {
132 constant_pool = Memory::Address_at(
133 entry + ExitFrameConstants::kConstantPoolOffset);
134 }
130 Address* pc_address = 135 Address* pc_address =
131 reinterpret_cast<Address*>(entry + ExitFrameConstants::kCallerPCOffset); 136 reinterpret_cast<Address*>(entry + ExitFrameConstants::kCallerPCOffset);
132 Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset); 137 Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset);
133 // If there's another JavaScript frame on the stack or a 138 // If there's another JavaScript frame on the stack or a
134 // StubFailureTrampoline, we need to look one frame further down the stack to 139 // StubFailureTrampoline, we need to look one frame further down the stack to
135 // find the frame pointer and the return address stack slot. 140 // find the frame pointer and the return address stack slot.
136 if (depth == EXTRA_CALL_FRAME) { 141 if (depth == EXTRA_CALL_FRAME) {
142 if (FLAG_enable_ool_constant_pool) {
143 constant_pool = Memory::Address_at(
144 fp + StandardFrameConstants::kConstantPoolOffset);
145 }
137 const int kCallerPCOffset = StandardFrameConstants::kCallerPCOffset; 146 const int kCallerPCOffset = StandardFrameConstants::kCallerPCOffset;
138 pc_address = reinterpret_cast<Address*>(fp + kCallerPCOffset); 147 pc_address = reinterpret_cast<Address*>(fp + kCallerPCOffset);
139 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); 148 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset);
140 } 149 }
141 #ifdef DEBUG 150 #ifdef DEBUG
142 StackFrameIterator it(isolate); 151 StackFrameIterator it(isolate);
143 for (int i = 0; i < depth + 1; i++) it.Advance(); 152 for (int i = 0; i < depth + 1; i++) it.Advance();
144 StackFrame* frame = it.frame(); 153 StackFrame* frame = it.frame();
145 ASSERT(fp == frame->fp() && pc_address == frame->pc_address()); 154 ASSERT(fp == frame->fp() && pc_address == frame->pc_address());
146 #endif 155 #endif
147 fp_ = fp; 156 fp_ = fp;
157 if (FLAG_enable_ool_constant_pool) {
158 raw_constant_pool_ = handle(
159 ConstantPoolArray::cast(reinterpret_cast<Object*>(constant_pool)),
160 isolate);
161 }
148 pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address); 162 pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address);
149 target_ = handle(raw_target(), isolate); 163 target_ = handle(raw_target(), isolate);
150 state_ = target_->ic_state(); 164 state_ = target_->ic_state();
151 extra_ic_state_ = target_->extra_ic_state(); 165 extra_ic_state_ = target_->extra_ic_state();
152 } 166 }
153 167
154 168
155 #ifdef ENABLE_DEBUGGER_SUPPORT 169 #ifdef ENABLE_DEBUGGER_SUPPORT
156 Address IC::OriginalCodeAddress() const { 170 SharedFunctionInfo* IC::GetSharedFunctionInfo() const {
157 HandleScope scope(isolate());
158 // Compute the JavaScript frame for the frame pointer of this IC 171 // Compute the JavaScript frame for the frame pointer of this IC
159 // structure. We need this to be able to find the function 172 // structure. We need this to be able to find the function
160 // corresponding to the frame. 173 // corresponding to the frame.
161 StackFrameIterator it(isolate()); 174 StackFrameIterator it(isolate());
162 while (it.frame()->fp() != this->fp()) it.Advance(); 175 while (it.frame()->fp() != this->fp()) it.Advance();
163 JavaScriptFrame* frame = JavaScriptFrame::cast(it.frame()); 176 JavaScriptFrame* frame = JavaScriptFrame::cast(it.frame());
164 // Find the function on the stack and both the active code for the 177 // Find the function on the stack and both the active code for the
165 // function and the original code. 178 // function and the original code.
166 JSFunction* function = frame->function(); 179 JSFunction* function = frame->function();
167 Handle<SharedFunctionInfo> shared(function->shared(), isolate()); 180 return function->shared();
181 }
182
183
184 Code* IC::GetCode() const {
185 HandleScope scope(isolate());
186 Handle<SharedFunctionInfo> shared(GetSharedFunctionInfo(), isolate());
168 Code* code = shared->code(); 187 Code* code = shared->code();
188 return code;
189 }
190
191
192 Code* IC::GetOriginalCode() const {
193 HandleScope scope(isolate());
194 Handle<SharedFunctionInfo> shared(GetSharedFunctionInfo(), isolate());
169 ASSERT(Debug::HasDebugInfo(shared)); 195 ASSERT(Debug::HasDebugInfo(shared));
170 Code* original_code = Debug::GetDebugInfo(shared)->original_code(); 196 Code* original_code = Debug::GetDebugInfo(shared)->original_code();
171 ASSERT(original_code->IsCode()); 197 ASSERT(original_code->IsCode());
172 // Get the address of the call site in the active code. This is the 198 return original_code;
173 // place where the call to DebugBreakXXX is and where the IC
174 // normally would be.
175 Address addr = Assembler::target_address_from_return_address(pc());
176 // Return the address in the original code. This is the place where
177 // the call which has been overwritten by the DebugBreakXXX resides
178 // and the place where the inline cache system should look.
179 intptr_t delta =
180 original_code->instruction_start() - code->instruction_start();
181 return addr + delta;
182 } 199 }
183 #endif 200 #endif
184 201
185 202
186 static bool HasInterceptorGetter(JSObject* object) { 203 static bool HasInterceptorGetter(JSObject* object) {
187 return !object->GetNamedInterceptor()->getter()->IsUndefined(); 204 return !object->GetNamedInterceptor()->getter()->IsUndefined();
188 } 205 }
189 206
190 207
191 static bool HasInterceptorSetter(JSObject* object) { 208 static bool HasInterceptorSetter(JSObject* object) {
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 info->change_own_type_change_checksum(); 419 info->change_own_type_change_checksum();
403 } 420 }
404 host->set_profiler_ticks(0); 421 host->set_profiler_ticks(0);
405 isolate->runtime_profiler()->NotifyICChanged(); 422 isolate->runtime_profiler()->NotifyICChanged();
406 // TODO(2029): When an optimized function is patched, it would 423 // TODO(2029): When an optimized function is patched, it would
407 // be nice to propagate the corresponding type information to its 424 // be nice to propagate the corresponding type information to its
408 // unoptimized version for the benefit of later inlining. 425 // unoptimized version for the benefit of later inlining.
409 } 426 }
410 427
411 428
412 void IC::Clear(Isolate* isolate, Address address) { 429 void IC::Clear(Isolate* isolate, Address address,
413 Code* target = GetTargetAtAddress(address); 430 ConstantPoolArray* constant_pool) {
431 Code* target = GetTargetAtAddress(address, constant_pool);
414 432
415 // Don't clear debug break inline cache as it will remove the break point. 433 // Don't clear debug break inline cache as it will remove the break point.
416 if (target->is_debug_stub()) return; 434 if (target->is_debug_stub()) return;
417 435
418 switch (target->kind()) { 436 switch (target->kind()) {
419 case Code::LOAD_IC: return LoadIC::Clear(isolate, address, target); 437 case Code::LOAD_IC:
438 return LoadIC::Clear(isolate, address, target, constant_pool);
420 case Code::KEYED_LOAD_IC: 439 case Code::KEYED_LOAD_IC:
421 return KeyedLoadIC::Clear(isolate, address, target); 440 return KeyedLoadIC::Clear(isolate, address, target, constant_pool);
422 case Code::STORE_IC: return StoreIC::Clear(isolate, address, target); 441 case Code::STORE_IC:
442 return StoreIC::Clear(isolate, address, target, constant_pool);
423 case Code::KEYED_STORE_IC: 443 case Code::KEYED_STORE_IC:
424 return KeyedStoreIC::Clear(isolate, address, target); 444 return KeyedStoreIC::Clear(isolate, address, target, constant_pool);
425 case Code::COMPARE_IC: return CompareIC::Clear(isolate, address, target); 445 case Code::COMPARE_IC:
426 case Code::COMPARE_NIL_IC: return CompareNilIC::Clear(address, target); 446 return CompareIC::Clear(isolate, address, target, constant_pool);
447 case Code::COMPARE_NIL_IC:
448 return CompareNilIC::Clear(address, target, constant_pool);
427 case Code::BINARY_OP_IC: 449 case Code::BINARY_OP_IC:
428 case Code::TO_BOOLEAN_IC: 450 case Code::TO_BOOLEAN_IC:
429 // Clearing these is tricky and does not 451 // Clearing these is tricky and does not
430 // make any performance difference. 452 // make any performance difference.
431 return; 453 return;
432 default: UNREACHABLE(); 454 default: UNREACHABLE();
433 } 455 }
434 } 456 }
435 457
436 458
437 void KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target) { 459 void KeyedLoadIC::Clear(Isolate* isolate,
460 Address address,
461 Code* target,
462 ConstantPoolArray* constant_pool) {
438 if (IsCleared(target)) return; 463 if (IsCleared(target)) return;
439 // Make sure to also clear the map used in inline fast cases. If we 464 // Make sure to also clear the map used in inline fast cases. If we
440 // do not clear these maps, cached code can keep objects alive 465 // do not clear these maps, cached code can keep objects alive
441 // through the embedded maps. 466 // through the embedded maps.
442 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate)); 467 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate), constant_pool);
443 } 468 }
444 469
445 470
446 void LoadIC::Clear(Isolate* isolate, Address address, Code* target) { 471 void LoadIC::Clear(Isolate* isolate,
472 Address address,
473 Code* target,
474 ConstantPoolArray* constant_pool) {
447 if (IsCleared(target)) return; 475 if (IsCleared(target)) return;
448 Code* code = target->GetIsolate()->stub_cache()->FindPreMonomorphicIC( 476 Code* code = target->GetIsolate()->stub_cache()->FindPreMonomorphicIC(
449 Code::LOAD_IC, target->extra_ic_state()); 477 Code::LOAD_IC, target->extra_ic_state());
450 SetTargetAtAddress(address, code); 478 SetTargetAtAddress(address, code, constant_pool);
451 } 479 }
452 480
453 481
454 void StoreIC::Clear(Isolate* isolate, Address address, Code* target) { 482 void StoreIC::Clear(Isolate* isolate,
483 Address address,
484 Code* target,
485 ConstantPoolArray* constant_pool) {
455 if (IsCleared(target)) return; 486 if (IsCleared(target)) return;
456 Code* code = target->GetIsolate()->stub_cache()->FindPreMonomorphicIC( 487 Code* code = target->GetIsolate()->stub_cache()->FindPreMonomorphicIC(
457 Code::STORE_IC, target->extra_ic_state()); 488 Code::STORE_IC, target->extra_ic_state());
458 SetTargetAtAddress(address, code); 489 SetTargetAtAddress(address, code, constant_pool);
459 } 490 }
460 491
461 492
462 void KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target) { 493 void KeyedStoreIC::Clear(Isolate* isolate,
494 Address address,
495 Code* target,
496 ConstantPoolArray* constant_pool) {
463 if (IsCleared(target)) return; 497 if (IsCleared(target)) return;
464 SetTargetAtAddress(address, 498 SetTargetAtAddress(address,
465 *pre_monomorphic_stub( 499 *pre_monomorphic_stub(
466 isolate, StoreIC::GetStrictMode(target->extra_ic_state()))); 500 isolate, StoreIC::GetStrictMode(target->extra_ic_state())),
501 constant_pool);
467 } 502 }
468 503
469 504
470 void CompareIC::Clear(Isolate* isolate, Address address, Code* target) { 505 void CompareIC::Clear(Isolate* isolate,
506 Address address,
507 Code* target,
508 ConstantPoolArray* constant_pool) {
471 ASSERT(target->major_key() == CodeStub::CompareIC); 509 ASSERT(target->major_key() == CodeStub::CompareIC);
472 CompareIC::State handler_state; 510 CompareIC::State handler_state;
473 Token::Value op; 511 Token::Value op;
474 ICCompareStub::DecodeMinorKey(target->stub_info(), NULL, NULL, 512 ICCompareStub::DecodeMinorKey(target->stub_info(), NULL, NULL,
475 &handler_state, &op); 513 &handler_state, &op);
476 // Only clear CompareICs that can retain objects. 514 // Only clear CompareICs that can retain objects.
477 if (handler_state != KNOWN_OBJECT) return; 515 if (handler_state != KNOWN_OBJECT) return;
478 SetTargetAtAddress(address, GetRawUninitialized(isolate, op)); 516 SetTargetAtAddress(address, GetRawUninitialized(isolate, op), constant_pool);
479 PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK); 517 PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK);
480 } 518 }
481 519
482 520
483 static bool MigrateDeprecated(Handle<Object> object) { 521 static bool MigrateDeprecated(Handle<Object> object) {
484 if (!object->IsJSObject()) return false; 522 if (!object->IsJSObject()) return false;
485 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 523 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
486 if (!receiver->map()->is_deprecated()) return false; 524 if (!receiver->map()->is_deprecated()) return false;
487 JSObject::MigrateInstance(Handle<JSObject>::cast(object)); 525 JSObject::MigrateInstance(Handle<JSObject>::cast(object));
488 return true; 526 return true;
(...skipping 2189 matching lines...) Expand 10 before | Expand all | Expand 10 after
2678 2716
2679 // Used from ICCompareStub::GenerateMiss in code-stubs-<arch>.cc. 2717 // Used from ICCompareStub::GenerateMiss in code-stubs-<arch>.cc.
2680 RUNTIME_FUNCTION(Code*, CompareIC_Miss) { 2718 RUNTIME_FUNCTION(Code*, CompareIC_Miss) {
2681 HandleScope scope(isolate); 2719 HandleScope scope(isolate);
2682 ASSERT(args.length() == 3); 2720 ASSERT(args.length() == 3);
2683 CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2))); 2721 CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2)));
2684 return ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); 2722 return ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1));
2685 } 2723 }
2686 2724
2687 2725
2688 void CompareNilIC::Clear(Address address, Code* target) { 2726 void CompareNilIC::Clear(Address address,
2727 Code* target,
2728 ConstantPoolArray* constant_pool) {
2689 if (IsCleared(target)) return; 2729 if (IsCleared(target)) return;
2690 ExtraICState state = target->extra_ic_state(); 2730 ExtraICState state = target->extra_ic_state();
2691 2731
2692 CompareNilICStub stub(state, HydrogenCodeStub::UNINITIALIZED); 2732 CompareNilICStub stub(state, HydrogenCodeStub::UNINITIALIZED);
2693 stub.ClearState(); 2733 stub.ClearState();
2694 2734
2695 Code* code = NULL; 2735 Code* code = NULL;
2696 CHECK(stub.FindCodeInCache(&code, target->GetIsolate())); 2736 CHECK(stub.FindCodeInCache(&code, target->GetIsolate()));
2697 2737
2698 SetTargetAtAddress(address, code); 2738 SetTargetAtAddress(address, code, constant_pool);
2699 } 2739 }
2700 2740
2701 2741
2702 MaybeObject* CompareNilIC::DoCompareNilSlow(NilValue nil, 2742 MaybeObject* CompareNilIC::DoCompareNilSlow(NilValue nil,
2703 Handle<Object> object) { 2743 Handle<Object> object) {
2704 if (object->IsNull() || object->IsUndefined()) { 2744 if (object->IsNull() || object->IsUndefined()) {
2705 return Smi::FromInt(true); 2745 return Smi::FromInt(true);
2706 } 2746 }
2707 return Smi::FromInt(object->IsUndetectableObject()); 2747 return Smi::FromInt(object->IsUndetectableObject());
2708 } 2748 }
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2817 #undef ADDR 2857 #undef ADDR
2818 }; 2858 };
2819 2859
2820 2860
2821 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2861 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2822 return IC_utilities[id]; 2862 return IC_utilities[id];
2823 } 2863 }
2824 2864
2825 2865
2826 } } // namespace v8::internal 2866 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/ic-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698