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

Side by Side Diff: src/deoptimizer.cc

Issue 2028983002: Introduce IsUndefined(Isolate*) and IsTheHole(Isolate*) (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase master Created 4 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
« no previous file with comments | « src/debug/liveedit.cc ('k') | src/elements.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/deoptimizer.h" 5 #include "src/deoptimizer.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/ast/prettyprinter.h" 8 #include "src/ast/prettyprinter.h"
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/disasm.h" 10 #include "src/disasm.h"
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 for (int i = 0; i <= Deoptimizer::kLastBailoutType; ++i) { 49 for (int i = 0; i <= Deoptimizer::kLastBailoutType; ++i) {
50 allocator_->Free<MemoryAllocator::kFull>(deopt_entry_code_[i]); 50 allocator_->Free<MemoryAllocator::kFull>(deopt_entry_code_[i]);
51 deopt_entry_code_[i] = NULL; 51 deopt_entry_code_[i] = NULL;
52 } 52 }
53 } 53 }
54 54
55 55
56 Code* Deoptimizer::FindDeoptimizingCode(Address addr) { 56 Code* Deoptimizer::FindDeoptimizingCode(Address addr) {
57 if (function_->IsHeapObject()) { 57 if (function_->IsHeapObject()) {
58 // Search all deoptimizing code in the native context of the function. 58 // Search all deoptimizing code in the native context of the function.
59 Isolate* isolate = function_->GetIsolate();
59 Context* native_context = function_->context()->native_context(); 60 Context* native_context = function_->context()->native_context();
60 Object* element = native_context->DeoptimizedCodeListHead(); 61 Object* element = native_context->DeoptimizedCodeListHead();
61 while (!element->IsUndefined()) { 62 while (!element->IsUndefined(isolate)) {
62 Code* code = Code::cast(element); 63 Code* code = Code::cast(element);
63 CHECK(code->kind() == Code::OPTIMIZED_FUNCTION); 64 CHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
64 if (code->contains(addr)) return code; 65 if (code->contains(addr)) return code;
65 element = code->next_code_link(); 66 element = code->next_code_link();
66 } 67 }
67 } 68 }
68 return NULL; 69 return NULL;
69 } 70 }
70 71
71 72
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 DisallowHeapAllocation no_allocation; 180 DisallowHeapAllocation no_allocation;
180 181
181 CHECK(context->IsNativeContext()); 182 CHECK(context->IsNativeContext());
182 183
183 visitor->EnterContext(context); 184 visitor->EnterContext(context);
184 185
185 // Visit the list of optimized functions, removing elements that 186 // Visit the list of optimized functions, removing elements that
186 // no longer refer to optimized code. 187 // no longer refer to optimized code.
187 JSFunction* prev = NULL; 188 JSFunction* prev = NULL;
188 Object* element = context->OptimizedFunctionsListHead(); 189 Object* element = context->OptimizedFunctionsListHead();
189 while (!element->IsUndefined()) { 190 Isolate* isolate = context->GetIsolate();
191 while (!element->IsUndefined(isolate)) {
190 JSFunction* function = JSFunction::cast(element); 192 JSFunction* function = JSFunction::cast(element);
191 Object* next = function->next_function_link(); 193 Object* next = function->next_function_link();
192 if (function->code()->kind() != Code::OPTIMIZED_FUNCTION || 194 if (function->code()->kind() != Code::OPTIMIZED_FUNCTION ||
193 (visitor->VisitFunction(function), 195 (visitor->VisitFunction(function),
194 function->code()->kind() != Code::OPTIMIZED_FUNCTION)) { 196 function->code()->kind() != Code::OPTIMIZED_FUNCTION)) {
195 // The function no longer refers to optimized code, or the visitor 197 // The function no longer refers to optimized code, or the visitor
196 // changed the code to which it refers to no longer be optimized code. 198 // changed the code to which it refers to no longer be optimized code.
197 // Remove the function from this list. 199 // Remove the function from this list.
198 if (prev != NULL) { 200 if (prev != NULL) {
199 prev->set_next_function_link(next, UPDATE_WEAK_WRITE_BARRIER); 201 prev->set_next_function_link(next, UPDATE_WEAK_WRITE_BARRIER);
(...skipping 19 matching lines...) Expand all
219 } 221 }
220 222
221 223
222 void Deoptimizer::VisitAllOptimizedFunctions( 224 void Deoptimizer::VisitAllOptimizedFunctions(
223 Isolate* isolate, 225 Isolate* isolate,
224 OptimizedFunctionVisitor* visitor) { 226 OptimizedFunctionVisitor* visitor) {
225 DisallowHeapAllocation no_allocation; 227 DisallowHeapAllocation no_allocation;
226 228
227 // Run through the list of all native contexts. 229 // Run through the list of all native contexts.
228 Object* context = isolate->heap()->native_contexts_list(); 230 Object* context = isolate->heap()->native_contexts_list();
229 while (!context->IsUndefined()) { 231 while (!context->IsUndefined(isolate)) {
230 VisitAllOptimizedFunctionsForContext(Context::cast(context), visitor); 232 VisitAllOptimizedFunctionsForContext(Context::cast(context), visitor);
231 context = Context::cast(context)->next_context_link(); 233 context = Context::cast(context)->next_context_link();
232 } 234 }
233 } 235 }
234 236
235 237
236 // Unlink functions referring to code marked for deoptimization, then move 238 // Unlink functions referring to code marked for deoptimization, then move
237 // marked code from the optimized code list to the deoptimized code list, 239 // marked code from the optimized code list to the deoptimized code list,
238 // and patch code for lazy deopt. 240 // and patch code for lazy deopt.
239 void Deoptimizer::DeoptimizeMarkedCodeForContext(Context* context) { 241 void Deoptimizer::DeoptimizeMarkedCodeForContext(Context* context) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 #endif 310 #endif
309 311
310 // Move marked code from the optimized code list to the deoptimized 312 // Move marked code from the optimized code list to the deoptimized
311 // code list, collecting them into a ZoneList. 313 // code list, collecting them into a ZoneList.
312 Zone zone(isolate->allocator()); 314 Zone zone(isolate->allocator());
313 ZoneList<Code*> codes(10, &zone); 315 ZoneList<Code*> codes(10, &zone);
314 316
315 // Walk over all optimized code objects in this native context. 317 // Walk over all optimized code objects in this native context.
316 Code* prev = NULL; 318 Code* prev = NULL;
317 Object* element = context->OptimizedCodeListHead(); 319 Object* element = context->OptimizedCodeListHead();
318 while (!element->IsUndefined()) { 320 while (!element->IsUndefined(isolate)) {
319 Code* code = Code::cast(element); 321 Code* code = Code::cast(element);
320 CHECK_EQ(code->kind(), Code::OPTIMIZED_FUNCTION); 322 CHECK_EQ(code->kind(), Code::OPTIMIZED_FUNCTION);
321 Object* next = code->next_code_link(); 323 Object* next = code->next_code_link();
322 324
323 if (code->marked_for_deoptimization()) { 325 if (code->marked_for_deoptimization()) {
324 // Put the code into the list for later patching. 326 // Put the code into the list for later patching.
325 codes.Add(code, &zone); 327 codes.Add(code, &zone);
326 328
327 if (prev != NULL) { 329 if (prev != NULL) {
328 // Skip this code in the optimized code list. 330 // Skip this code in the optimized code list.
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 &RuntimeCallStats::DeoptimizeCode); 380 &RuntimeCallStats::DeoptimizeCode);
379 TimerEventScope<TimerEventDeoptimizeCode> timer(isolate); 381 TimerEventScope<TimerEventDeoptimizeCode> timer(isolate);
380 TRACE_EVENT0("v8", "V8.DeoptimizeCode"); 382 TRACE_EVENT0("v8", "V8.DeoptimizeCode");
381 if (FLAG_trace_deopt) { 383 if (FLAG_trace_deopt) {
382 CodeTracer::Scope scope(isolate->GetCodeTracer()); 384 CodeTracer::Scope scope(isolate->GetCodeTracer());
383 PrintF(scope.file(), "[deoptimize all code in all contexts]\n"); 385 PrintF(scope.file(), "[deoptimize all code in all contexts]\n");
384 } 386 }
385 DisallowHeapAllocation no_allocation; 387 DisallowHeapAllocation no_allocation;
386 // For all contexts, mark all code, then deoptimize. 388 // For all contexts, mark all code, then deoptimize.
387 Object* context = isolate->heap()->native_contexts_list(); 389 Object* context = isolate->heap()->native_contexts_list();
388 while (!context->IsUndefined()) { 390 while (!context->IsUndefined(isolate)) {
389 Context* native_context = Context::cast(context); 391 Context* native_context = Context::cast(context);
390 MarkAllCodeForContext(native_context); 392 MarkAllCodeForContext(native_context);
391 DeoptimizeMarkedCodeForContext(native_context); 393 DeoptimizeMarkedCodeForContext(native_context);
392 context = native_context->next_context_link(); 394 context = native_context->next_context_link();
393 } 395 }
394 } 396 }
395 397
396 398
397 void Deoptimizer::DeoptimizeMarkedCode(Isolate* isolate) { 399 void Deoptimizer::DeoptimizeMarkedCode(Isolate* isolate) {
398 RuntimeCallTimerScope runtimeTimer(isolate, 400 RuntimeCallTimerScope runtimeTimer(isolate,
399 &RuntimeCallStats::DeoptimizeCode); 401 &RuntimeCallStats::DeoptimizeCode);
400 TimerEventScope<TimerEventDeoptimizeCode> timer(isolate); 402 TimerEventScope<TimerEventDeoptimizeCode> timer(isolate);
401 TRACE_EVENT0("v8", "V8.DeoptimizeCode"); 403 TRACE_EVENT0("v8", "V8.DeoptimizeCode");
402 if (FLAG_trace_deopt) { 404 if (FLAG_trace_deopt) {
403 CodeTracer::Scope scope(isolate->GetCodeTracer()); 405 CodeTracer::Scope scope(isolate->GetCodeTracer());
404 PrintF(scope.file(), "[deoptimize marked code in all contexts]\n"); 406 PrintF(scope.file(), "[deoptimize marked code in all contexts]\n");
405 } 407 }
406 DisallowHeapAllocation no_allocation; 408 DisallowHeapAllocation no_allocation;
407 // For all contexts, deoptimize code already marked. 409 // For all contexts, deoptimize code already marked.
408 Object* context = isolate->heap()->native_contexts_list(); 410 Object* context = isolate->heap()->native_contexts_list();
409 while (!context->IsUndefined()) { 411 while (!context->IsUndefined(isolate)) {
410 Context* native_context = Context::cast(context); 412 Context* native_context = Context::cast(context);
411 DeoptimizeMarkedCodeForContext(native_context); 413 DeoptimizeMarkedCodeForContext(native_context);
412 context = native_context->next_context_link(); 414 context = native_context->next_context_link();
413 } 415 }
414 } 416 }
415 417
416 418
417 void Deoptimizer::MarkAllCodeForContext(Context* context) { 419 void Deoptimizer::MarkAllCodeForContext(Context* context) {
418 Object* element = context->OptimizedCodeListHead(); 420 Object* element = context->OptimizedCodeListHead();
419 while (!element->IsUndefined()) { 421 Isolate* isolate = context->GetIsolate();
422 while (!element->IsUndefined(isolate)) {
420 Code* code = Code::cast(element); 423 Code* code = Code::cast(element);
421 CHECK_EQ(code->kind(), Code::OPTIMIZED_FUNCTION); 424 CHECK_EQ(code->kind(), Code::OPTIMIZED_FUNCTION);
422 code->set_marked_for_deoptimization(true); 425 code->set_marked_for_deoptimization(true);
423 element = code->next_code_link(); 426 element = code->next_code_link();
424 } 427 }
425 } 428 }
426 429
427 430
428 void Deoptimizer::DeoptimizeFunction(JSFunction* function) { 431 void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
429 Isolate* isolate = function->GetIsolate(); 432 Isolate* isolate = function->GetIsolate();
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 0xfefefeff); 656 0xfefefeff);
654 FATAL("unable to find pc offset during deoptimization"); 657 FATAL("unable to find pc offset during deoptimization");
655 return -1; 658 return -1;
656 } 659 }
657 660
658 661
659 int Deoptimizer::GetDeoptimizedCodeCount(Isolate* isolate) { 662 int Deoptimizer::GetDeoptimizedCodeCount(Isolate* isolate) {
660 int length = 0; 663 int length = 0;
661 // Count all entries in the deoptimizing code list of every context. 664 // Count all entries in the deoptimizing code list of every context.
662 Object* context = isolate->heap()->native_contexts_list(); 665 Object* context = isolate->heap()->native_contexts_list();
663 while (!context->IsUndefined()) { 666 while (!context->IsUndefined(isolate)) {
664 Context* native_context = Context::cast(context); 667 Context* native_context = Context::cast(context);
665 Object* element = native_context->DeoptimizedCodeListHead(); 668 Object* element = native_context->DeoptimizedCodeListHead();
666 while (!element->IsUndefined()) { 669 while (!element->IsUndefined(isolate)) {
667 Code* code = Code::cast(element); 670 Code* code = Code::cast(element);
668 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION); 671 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION);
669 length++; 672 length++;
670 element = code->next_code_link(); 673 element = code->next_code_link();
671 } 674 }
672 context = Context::cast(context)->next_context_link(); 675 context = Context::cast(context)->next_context_link();
673 } 676 }
674 return length; 677 return length;
675 } 678 }
676 679
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
982 // from just above the top of the operand stack (we push the context 985 // from just above the top of the operand stack (we push the context
983 // at the entry of the try block). 986 // at the entry of the try block).
984 if (goto_catch_handler) { 987 if (goto_catch_handler) {
985 for (unsigned i = 0; i < height + 1; ++i) { 988 for (unsigned i = 0; i < height + 1; ++i) {
986 context_pos++; 989 context_pos++;
987 context_input_index++; 990 context_input_index++;
988 } 991 }
989 } 992 }
990 // Read the context from the translations. 993 // Read the context from the translations.
991 Object* context = context_pos->GetRawValue(); 994 Object* context = context_pos->GetRawValue();
992 if (context == isolate_->heap()->undefined_value()) { 995 if (context->IsUndefined(isolate_)) {
993 // If the context was optimized away, just use the context from 996 // If the context was optimized away, just use the context from
994 // the activation. This should only apply to Crankshaft code. 997 // the activation. This should only apply to Crankshaft code.
995 CHECK(!compiled_code_->is_turbofanned()); 998 CHECK(!compiled_code_->is_turbofanned());
996 context = is_bottommost ? reinterpret_cast<Object*>(input_frame_context_) 999 context = is_bottommost ? reinterpret_cast<Object*>(input_frame_context_)
997 : function->context(); 1000 : function->context();
998 } 1001 }
999 value = reinterpret_cast<intptr_t>(context); 1002 value = reinterpret_cast<intptr_t>(context);
1000 output_frame->SetContext(value); 1003 output_frame->SetContext(value);
1001 if (is_topmost) { 1004 if (is_topmost) {
1002 Register context_reg = JavaScriptFrame::context_register(); 1005 Register context_reg = JavaScriptFrame::context_register();
(...skipping 2779 matching lines...) Expand 10 before | Expand all | Expand 10 after
3782 Handle<Object> next_link = MaterializeAt(frame_index, value_index); 3785 Handle<Object> next_link = MaterializeAt(frame_index, value_index);
3783 object->ReplaceCode(*isolate_->builtins()->CompileLazy()); 3786 object->ReplaceCode(*isolate_->builtins()->CompileLazy());
3784 object->set_map(*map); 3787 object->set_map(*map);
3785 object->set_properties(FixedArray::cast(*properties)); 3788 object->set_properties(FixedArray::cast(*properties));
3786 object->set_elements(FixedArrayBase::cast(*elements)); 3789 object->set_elements(FixedArrayBase::cast(*elements));
3787 object->set_prototype_or_initial_map(*prototype); 3790 object->set_prototype_or_initial_map(*prototype);
3788 object->set_shared(SharedFunctionInfo::cast(*shared)); 3791 object->set_shared(SharedFunctionInfo::cast(*shared));
3789 object->set_context(Context::cast(*context)); 3792 object->set_context(Context::cast(*context));
3790 object->set_literals(LiteralsArray::cast(*literals)); 3793 object->set_literals(LiteralsArray::cast(*literals));
3791 CHECK(entry->IsNumber()); // Entry to compile lazy stub. 3794 CHECK(entry->IsNumber()); // Entry to compile lazy stub.
3792 CHECK(next_link->IsUndefined()); 3795 CHECK(next_link->IsUndefined(isolate_));
3793 return object; 3796 return object;
3794 } 3797 }
3795 case FIXED_ARRAY_TYPE: { 3798 case FIXED_ARRAY_TYPE: {
3796 Handle<Object> lengthObject = MaterializeAt(frame_index, value_index); 3799 Handle<Object> lengthObject = MaterializeAt(frame_index, value_index);
3797 int32_t length = 0; 3800 int32_t length = 0;
3798 CHECK(lengthObject->ToInt32(&length)); 3801 CHECK(lengthObject->ToInt32(&length));
3799 Handle<FixedArray> object = 3802 Handle<FixedArray> object =
3800 isolate_->factory()->NewFixedArray(length); 3803 isolate_->factory()->NewFixedArray(length);
3801 // We need to set the map, because the fixed array we are 3804 // We need to set the map, because the fixed array we are
3802 // materializing could be a context or an arguments object, 3805 // materializing could be a context or an arguments object,
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
4014 CHECK(value_info->IsMaterializedObject()); 4017 CHECK(value_info->IsMaterializedObject());
4015 4018
4016 value_info->value_ = 4019 value_info->value_ =
4017 Handle<Object>(previously_materialized_objects->get(i), isolate_); 4020 Handle<Object>(previously_materialized_objects->get(i), isolate_);
4018 } 4021 }
4019 } 4022 }
4020 } 4023 }
4021 4024
4022 } // namespace internal 4025 } // namespace internal
4023 } // namespace v8 4026 } // namespace v8
OLDNEW
« no previous file with comments | « src/debug/liveedit.cc ('k') | src/elements.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698