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

Side by Side Diff: src/ia32/deoptimizer-ia32.cc

Issue 6793013: Cache optimized code on shared function info. Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 8 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/ia32/codegen-ia32.cc ('k') | src/ia32/full-codegen-ia32.cc » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 } 127 }
128 // Replace relocation information on the code object. 128 // Replace relocation information on the code object.
129 code->set_relocation_info(*new_reloc); 129 code->set_relocation_info(*new_reloc);
130 } 130 }
131 } 131 }
132 132
133 133
134 void Deoptimizer::DeoptimizeFunction(JSFunction* function) { 134 void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
135 if (!function->IsOptimized()) return; 135 if (!function->IsOptimized()) return;
136 136
137 // The optimized code is going to be patched, so we cannot use it
138 // any more. Play safe and reset the whole cache.
139 function->shared()->set_optimized_code_map(Smi::FromInt(0));
140
137 Isolate* isolate = function->GetIsolate(); 141 Isolate* isolate = function->GetIsolate();
138 HandleScope scope(isolate); 142 HandleScope scope(isolate);
139 AssertNoAllocation no_allocation; 143 AssertNoAllocation no_allocation;
140 144
141 // Get the optimized code. 145 // Get the optimized code.
142 Code* code = function->code(); 146 Code* code = function->code();
143 Address code_start_address = code->instruction_start(); 147 Address code_start_address = code->instruction_start();
144 148
145 // We will overwrite the code's relocation info in-place. Relocation info 149 // We will overwrite the code's relocation info in-place. Relocation info
146 // is written backward. The relocation info is the payload of a byte 150 // is written backward. The relocation info is the payload of a byte
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 ASSERT(junk_address <= reloc_end_address); 202 ASSERT(junk_address <= reloc_end_address);
199 isolate->heap()->CreateFillerObjectAt(junk_address, 203 isolate->heap()->CreateFillerObjectAt(junk_address,
200 reloc_end_address - junk_address); 204 reloc_end_address - junk_address);
201 205
202 // Add the deoptimizing code to the list. 206 // Add the deoptimizing code to the list.
203 DeoptimizingCodeListNode* node = new DeoptimizingCodeListNode(code); 207 DeoptimizingCodeListNode* node = new DeoptimizingCodeListNode(code);
204 DeoptimizerData* data = isolate->deoptimizer_data(); 208 DeoptimizerData* data = isolate->deoptimizer_data();
205 node->set_next(data->deoptimizing_code_list_); 209 node->set_next(data->deoptimizing_code_list_);
206 data->deoptimizing_code_list_ = node; 210 data->deoptimizing_code_list_ = node;
207 211
208 // Set the code for the function to non-optimized version. 212 // Iterate over all the functions which share the same code object
209 function->ReplaceCode(function->shared()->code()); 213 // and make them use unoptimized version.
214 Context* context = function->context()->global_context();
215 Object* element = context->get(Context::OPTIMIZED_FUNCTIONS_LIST);
216 SharedFunctionInfo* shared = function->shared();
217 while (!element->IsUndefined()) {
218 JSFunction* func = JSFunction::cast(element);
219 // Grab element before code replacement as ReplaceCode alters the list.
220 element = func->next_function_link();
221 if (func->shared() == shared) {
222 func->ReplaceCode(shared->code());
223 }
224 }
210 225
211 if (FLAG_trace_deopt) { 226 if (FLAG_trace_deopt) {
212 PrintF("[forced deoptimization: "); 227 PrintF("[forced deoptimization: ");
213 function->PrintName(); 228 function->PrintName();
214 PrintF(" / %x]\n", reinterpret_cast<uint32_t>(function)); 229 PrintF(" / %x]\n", reinterpret_cast<uint32_t>(function));
215 #ifdef DEBUG 230 #ifdef DEBUG
216 if (FLAG_print_code) { 231 if (FLAG_print_code) {
217 code->PrintLn(); 232 code->PrintLn();
218 } 233 }
219 #endif 234 #endif
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 int count = iterator.Next(); 324 int count = iterator.Next();
310 ASSERT(count == 1); 325 ASSERT(count == 1);
311 USE(count); 326 USE(count);
312 327
313 opcode = static_cast<Translation::Opcode>(iterator.Next()); 328 opcode = static_cast<Translation::Opcode>(iterator.Next());
314 USE(opcode); 329 USE(opcode);
315 ASSERT(Translation::FRAME == opcode); 330 ASSERT(Translation::FRAME == opcode);
316 unsigned node_id = iterator.Next(); 331 unsigned node_id = iterator.Next();
317 USE(node_id); 332 USE(node_id);
318 ASSERT(node_id == ast_id); 333 ASSERT(node_id == ast_id);
319 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator.Next())); 334 int closure_id = iterator.Next();
320 USE(function); 335 USE(closure_id);
321 ASSERT(function == function_); 336 ASSERT_EQ(Translation::kSelfLiteralId, closure_id);
322 unsigned height = iterator.Next(); 337 unsigned height = iterator.Next();
323 unsigned height_in_bytes = height * kPointerSize; 338 unsigned height_in_bytes = height * kPointerSize;
324 USE(height_in_bytes); 339 USE(height_in_bytes);
325 340
326 unsigned fixed_size = ComputeFixedSize(function_); 341 unsigned fixed_size = ComputeFixedSize(function_);
327 unsigned input_frame_size = input_->GetFrameSize(); 342 unsigned input_frame_size = input_->GetFrameSize();
328 ASSERT(fixed_size + height_in_bytes == input_frame_size); 343 ASSERT(fixed_size + height_in_bytes == input_frame_size);
329 344
330 unsigned stack_slot_size = optimized_code_->stack_slots() * kPointerSize; 345 unsigned stack_slot_size = optimized_code_->stack_slots() * kPointerSize;
331 unsigned outgoing_height = data->ArgumentsStackHeight(bailout_id)->value(); 346 unsigned outgoing_height = data->ArgumentsStackHeight(bailout_id)->value();
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 // Setup the frame pointer and the context pointer. 429 // Setup the frame pointer and the context pointer.
415 output_[0]->SetRegister(ebp.code(), input_->GetRegister(ebp.code())); 430 output_[0]->SetRegister(ebp.code(), input_->GetRegister(ebp.code()));
416 output_[0]->SetRegister(esi.code(), input_->GetRegister(esi.code())); 431 output_[0]->SetRegister(esi.code(), input_->GetRegister(esi.code()));
417 432
418 unsigned pc_offset = data->OsrPcOffset()->value(); 433 unsigned pc_offset = data->OsrPcOffset()->value();
419 uint32_t pc = reinterpret_cast<uint32_t>( 434 uint32_t pc = reinterpret_cast<uint32_t>(
420 optimized_code_->entry() + pc_offset); 435 optimized_code_->entry() + pc_offset);
421 output_[0]->SetPc(pc); 436 output_[0]->SetPc(pc);
422 } 437 }
423 Code* continuation = 438 Code* continuation =
424 function->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR); 439 function_->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR);
425 output_[0]->SetContinuation( 440 output_[0]->SetContinuation(
426 reinterpret_cast<uint32_t>(continuation->entry())); 441 reinterpret_cast<uint32_t>(continuation->entry()));
427 442
428 if (FLAG_trace_osr) { 443 if (FLAG_trace_osr) {
429 PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ", 444 PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ",
430 ok ? "finished" : "aborted", 445 ok ? "finished" : "aborted",
431 reinterpret_cast<intptr_t>(function)); 446 reinterpret_cast<intptr_t>(function_));
432 function->PrintName(); 447 function_->PrintName();
433 PrintF(" => pc=0x%0x]\n", output_[0]->GetPc()); 448 PrintF(" => pc=0x%0x]\n", output_[0]->GetPc());
434 } 449 }
435 } 450 }
436 451
437 452
438 void Deoptimizer::DoComputeFrame(TranslationIterator* iterator, 453 void Deoptimizer::DoComputeFrame(TranslationIterator* iterator,
439 int frame_index) { 454 int frame_index) {
440 // Read the ast node id, function, and frame height for this output frame. 455 // Read the ast node id, function, and frame height for this output frame.
441 Translation::Opcode opcode = 456 Translation::Opcode opcode =
442 static_cast<Translation::Opcode>(iterator->Next()); 457 static_cast<Translation::Opcode>(iterator->Next());
443 USE(opcode); 458 USE(opcode);
444 ASSERT(Translation::FRAME == opcode); 459 ASSERT(Translation::FRAME == opcode);
445 int node_id = iterator->Next(); 460 int node_id = iterator->Next();
446 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); 461 JSFunction* function;
462 if (frame_index != 0) {
463 function = JSFunction::cast(ComputeLiteral(iterator->Next()));
464 } else {
465 int closure_id = iterator->Next();
466 USE(closure_id);
467 ASSERT_EQ(Translation::kSelfLiteralId, closure_id);
468 function = function_;
469 }
447 unsigned height = iterator->Next(); 470 unsigned height = iterator->Next();
448 unsigned height_in_bytes = height * kPointerSize; 471 unsigned height_in_bytes = height * kPointerSize;
449 if (FLAG_trace_deopt) { 472 if (FLAG_trace_deopt) {
450 PrintF(" translating "); 473 PrintF(" translating ");
451 function->PrintName(); 474 function->PrintName();
452 PrintF(" => node=%d, height=%d\n", node_id, height_in_bytes); 475 PrintF(" => node=%d, height=%d\n", node_id, height_in_bytes);
453 } 476 }
454 477
455 // The 'fixed' part of the frame consists of the incoming parameters and 478 // The 'fixed' part of the frame consists of the incoming parameters and
456 // the part described by JavaScriptFrameConstants. 479 // the part described by JavaScriptFrameConstants.
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 } 788 }
766 __ bind(&done); 789 __ bind(&done);
767 } 790 }
768 791
769 #undef __ 792 #undef __
770 793
771 794
772 } } // namespace v8::internal 795 } } // namespace v8::internal
773 796
774 #endif // V8_TARGET_ARCH_IA32 797 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/codegen-ia32.cc ('k') | src/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698