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

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

Issue 10103035: Share optimized code for closures. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 8 years, 6 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/code-stubs-ia32.cc ('k') | src/ia32/lithium-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 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 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 } 110 }
111 // Replace relocation information on the code object. 111 // Replace relocation information on the code object.
112 code->set_relocation_info(*new_reloc); 112 code->set_relocation_info(*new_reloc);
113 } 113 }
114 } 114 }
115 115
116 116
117 void Deoptimizer::DeoptimizeFunction(JSFunction* function) { 117 void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
118 if (!function->IsOptimized()) return; 118 if (!function->IsOptimized()) return;
119 119
120 // The optimized code is going to be patched, so we cannot use it
121 // any more. Play safe and reset the whole cache.
122 function->shared()->ClearOptimizedCodeMap();
123
120 Isolate* isolate = function->GetIsolate(); 124 Isolate* isolate = function->GetIsolate();
121 HandleScope scope(isolate); 125 HandleScope scope(isolate);
122 AssertNoAllocation no_allocation; 126 AssertNoAllocation no_allocation;
123 127
124 // Get the optimized code. 128 // Get the optimized code.
125 Code* code = function->code(); 129 Code* code = function->code();
126 Address code_start_address = code->instruction_start(); 130 Address code_start_address = code->instruction_start();
127 131
128 // We will overwrite the code's relocation info in-place. Relocation info 132 // We will overwrite the code's relocation info in-place. Relocation info
129 // is written backward. The relocation info is the payload of a byte 133 // is written backward. The relocation info is the payload of a byte
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 DeoptimizingCodeListNode* node = new DeoptimizingCodeListNode(code); 191 DeoptimizingCodeListNode* node = new DeoptimizingCodeListNode(code);
188 DeoptimizerData* data = isolate->deoptimizer_data(); 192 DeoptimizerData* data = isolate->deoptimizer_data();
189 node->set_next(data->deoptimizing_code_list_); 193 node->set_next(data->deoptimizing_code_list_);
190 data->deoptimizing_code_list_ = node; 194 data->deoptimizing_code_list_ = node;
191 195
192 // We might be in the middle of incremental marking with compaction. 196 // We might be in the middle of incremental marking with compaction.
193 // Tell collector to treat this code object in a special way and 197 // Tell collector to treat this code object in a special way and
194 // ignore all slots that might have been recorded on it. 198 // ignore all slots that might have been recorded on it.
195 isolate->heap()->mark_compact_collector()->InvalidateCode(code); 199 isolate->heap()->mark_compact_collector()->InvalidateCode(code);
196 200
197 // Set the code for the function to non-optimized version. 201 // Iterate over all the functions which share the same code object
198 function->ReplaceCode(function->shared()->code()); 202 // and make them use unoptimized version.
203 Context* context = function->context()->global_context();
204 Object* element = context->get(Context::OPTIMIZED_FUNCTIONS_LIST);
205 SharedFunctionInfo* shared = function->shared();
206 while (!element->IsUndefined()) {
207 JSFunction* func = JSFunction::cast(element);
208 // Grab element before code replacement as ReplaceCode alters the list.
209 element = func->next_function_link();
210 if (func->code() == code) {
211 func->ReplaceCode(shared->code());
212 }
213 }
199 214
200 if (FLAG_trace_deopt) { 215 if (FLAG_trace_deopt) {
201 PrintF("[forced deoptimization: "); 216 PrintF("[forced deoptimization: ");
202 function->PrintName(); 217 function->PrintName();
203 PrintF(" / %x]\n", reinterpret_cast<uint32_t>(function)); 218 PrintF(" / %x]\n", reinterpret_cast<uint32_t>(function));
204 } 219 }
205 } 220 }
206 221
207 222
208 static const byte kJnsInstruction = 0x79; 223 static const byte kJnsInstruction = 0x79;
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 iterator.Next(); // Drop JS frames count. 338 iterator.Next(); // Drop JS frames count.
324 ASSERT(count == 1); 339 ASSERT(count == 1);
325 USE(count); 340 USE(count);
326 341
327 opcode = static_cast<Translation::Opcode>(iterator.Next()); 342 opcode = static_cast<Translation::Opcode>(iterator.Next());
328 USE(opcode); 343 USE(opcode);
329 ASSERT(Translation::JS_FRAME == opcode); 344 ASSERT(Translation::JS_FRAME == opcode);
330 unsigned node_id = iterator.Next(); 345 unsigned node_id = iterator.Next();
331 USE(node_id); 346 USE(node_id);
332 ASSERT(node_id == ast_id); 347 ASSERT(node_id == ast_id);
333 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator.Next())); 348 int closure_id = iterator.Next();
334 USE(function); 349 USE(closure_id);
335 ASSERT(function == function_); 350 ASSERT_EQ(Translation::kSelfLiteralId, closure_id);
336 unsigned height = iterator.Next(); 351 unsigned height = iterator.Next();
337 unsigned height_in_bytes = height * kPointerSize; 352 unsigned height_in_bytes = height * kPointerSize;
338 USE(height_in_bytes); 353 USE(height_in_bytes);
339 354
340 unsigned fixed_size = ComputeFixedSize(function_); 355 unsigned fixed_size = ComputeFixedSize(function_);
341 unsigned input_frame_size = input_->GetFrameSize(); 356 unsigned input_frame_size = input_->GetFrameSize();
342 ASSERT(fixed_size + height_in_bytes == input_frame_size); 357 ASSERT(fixed_size + height_in_bytes == input_frame_size);
343 358
344 unsigned stack_slot_size = optimized_code_->stack_slots() * kPointerSize; 359 unsigned stack_slot_size = optimized_code_->stack_slots() * kPointerSize;
345 unsigned outgoing_height = data->ArgumentsStackHeight(bailout_id)->value(); 360 unsigned outgoing_height = data->ArgumentsStackHeight(bailout_id)->value();
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 // Set up the frame pointer and the context pointer. 464 // Set up the frame pointer and the context pointer.
450 output_[0]->SetRegister(ebp.code(), frame_pointer); 465 output_[0]->SetRegister(ebp.code(), frame_pointer);
451 output_[0]->SetRegister(esi.code(), input_->GetRegister(esi.code())); 466 output_[0]->SetRegister(esi.code(), input_->GetRegister(esi.code()));
452 467
453 unsigned pc_offset = data->OsrPcOffset()->value(); 468 unsigned pc_offset = data->OsrPcOffset()->value();
454 uint32_t pc = reinterpret_cast<uint32_t>( 469 uint32_t pc = reinterpret_cast<uint32_t>(
455 optimized_code_->entry() + pc_offset); 470 optimized_code_->entry() + pc_offset);
456 output_[0]->SetPc(pc); 471 output_[0]->SetPc(pc);
457 } 472 }
458 Code* continuation = 473 Code* continuation =
459 function->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR); 474 function_->GetIsolate()->builtins()->builtin(Builtins::kNotifyOSR);
460 output_[0]->SetContinuation( 475 output_[0]->SetContinuation(
461 reinterpret_cast<uint32_t>(continuation->entry())); 476 reinterpret_cast<uint32_t>(continuation->entry()));
462 477
463 if (FLAG_trace_osr) { 478 if (FLAG_trace_osr) {
464 PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ", 479 PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ",
465 ok ? "finished" : "aborted", 480 ok ? "finished" : "aborted",
466 reinterpret_cast<intptr_t>(function)); 481 reinterpret_cast<intptr_t>(function_));
467 function->PrintName(); 482 function_->PrintName();
468 PrintF(" => pc=0x%0x]\n", output_[0]->GetPc()); 483 PrintF(" => pc=0x%0x]\n", output_[0]->GetPc());
469 } 484 }
470 } 485 }
471 486
472 487
473 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator, 488 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
474 int frame_index) { 489 int frame_index) {
475 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); 490 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
476 unsigned height = iterator->Next(); 491 unsigned height = iterator->Next();
477 unsigned height_in_bytes = height * kPointerSize; 492 unsigned height_in_bytes = height * kPointerSize;
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 uint32_t pc = reinterpret_cast<uint32_t>( 690 uint32_t pc = reinterpret_cast<uint32_t>(
676 construct_stub->instruction_start() + 691 construct_stub->instruction_start() +
677 isolate_->heap()->construct_stub_deopt_pc_offset()->value()); 692 isolate_->heap()->construct_stub_deopt_pc_offset()->value());
678 output_frame->SetPc(pc); 693 output_frame->SetPc(pc);
679 } 694 }
680 695
681 696
682 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, 697 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
683 int frame_index) { 698 int frame_index) {
684 int node_id = iterator->Next(); 699 int node_id = iterator->Next();
685 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); 700 JSFunction* function;
701 if (frame_index != 0) {
702 function = JSFunction::cast(ComputeLiteral(iterator->Next()));
703 } else {
704 int closure_id = iterator->Next();
705 USE(closure_id);
706 ASSERT_EQ(Translation::kSelfLiteralId, closure_id);
707 function = function_;
708 }
686 unsigned height = iterator->Next(); 709 unsigned height = iterator->Next();
687 unsigned height_in_bytes = height * kPointerSize; 710 unsigned height_in_bytes = height * kPointerSize;
688 if (FLAG_trace_deopt) { 711 if (FLAG_trace_deopt) {
689 PrintF(" translating "); 712 PrintF(" translating ");
690 function->PrintName(); 713 function->PrintName();
691 PrintF(" => node=%d, height=%d\n", node_id, height_in_bytes); 714 PrintF(" => node=%d, height=%d\n", node_id, height_in_bytes);
692 } 715 }
693 716
694 // The 'fixed' part of the frame consists of the incoming parameters and 717 // The 'fixed' part of the frame consists of the incoming parameters and
695 // the part described by JavaScriptFrameConstants. 718 // the part described by JavaScriptFrameConstants.
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
1071 } 1094 }
1072 __ bind(&done); 1095 __ bind(&done);
1073 } 1096 }
1074 1097
1075 #undef __ 1098 #undef __
1076 1099
1077 1100
1078 } } // namespace v8::internal 1101 } } // namespace v8::internal
1079 1102
1080 #endif // V8_TARGET_ARCH_IA32 1103 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/ia32/lithium-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698