OLD | NEW |
---|---|
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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
70 } | 70 } |
71 | 71 |
72 | 72 |
73 #ifdef ENABLE_DEBUGGER_SUPPORT | 73 #ifdef ENABLE_DEBUGGER_SUPPORT |
74 void DeoptimizerData::Iterate(ObjectVisitor* v) { | 74 void DeoptimizerData::Iterate(ObjectVisitor* v) { |
75 if (deoptimized_frame_info_ != NULL) { | 75 if (deoptimized_frame_info_ != NULL) { |
76 deoptimized_frame_info_->Iterate(v); | 76 deoptimized_frame_info_->Iterate(v); |
77 } | 77 } |
78 } | 78 } |
79 #endif | 79 #endif |
80 | 80 |
Jakob Kummerow
2012/11/28 16:28:22
nit: why remove the second empty line?
danno
2012/11/30 16:23:24
Done.
| |
81 | |
82 // We rely on this function not causing a GC. It is called from generated code | 81 // We rely on this function not causing a GC. It is called from generated code |
83 // without having a real stack frame in place. | 82 // without having a real stack frame in place. |
84 Deoptimizer* Deoptimizer::New(JSFunction* function, | 83 Deoptimizer* Deoptimizer::New(JSFunction* function, |
85 BailoutType type, | 84 BailoutType type, |
86 unsigned bailout_id, | 85 unsigned bailout_id, |
87 Address from, | 86 Address from, |
88 int fp_to_sp_delta, | 87 int fp_to_sp_delta, |
89 Isolate* isolate) { | 88 Isolate* isolate) { |
90 ASSERT(isolate == Isolate::Current()); | 89 ASSERT(isolate == Isolate::Current()); |
91 Deoptimizer* deoptimizer = new Deoptimizer(isolate, | 90 Deoptimizer* deoptimizer = new Deoptimizer(isolate, |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
403 reinterpret_cast<intptr_t>(from), | 402 reinterpret_cast<intptr_t>(from), |
404 fp_to_sp_delta - (2 * kPointerSize)); | 403 fp_to_sp_delta - (2 * kPointerSize)); |
405 } else if (FLAG_trace_osr && type == OSR) { | 404 } else if (FLAG_trace_osr && type == OSR) { |
406 PrintF("**** OSR: "); | 405 PrintF("**** OSR: "); |
407 function->PrintName(); | 406 function->PrintName(); |
408 PrintF(" at ast id #%u, address 0x%" V8PRIxPTR ", frame size %d\n", | 407 PrintF(" at ast id #%u, address 0x%" V8PRIxPTR ", frame size %d\n", |
409 bailout_id, | 408 bailout_id, |
410 reinterpret_cast<intptr_t>(from), | 409 reinterpret_cast<intptr_t>(from), |
411 fp_to_sp_delta - (2 * kPointerSize)); | 410 fp_to_sp_delta - (2 * kPointerSize)); |
412 } | 411 } |
413 function->shared()->increment_deopt_count(); | 412 // For COMPILED_STUBs called from builtins, the function pointer |
413 // is a SMI indicating an internal frame. | |
414 if (function->IsSmi()) { | |
415 function = NULL; | |
416 } | |
417 if (function != NULL && function->IsOptimized()) { | |
418 function->shared()->increment_deopt_count(); | |
419 } | |
414 // Find the optimized code. | 420 // Find the optimized code. |
415 if (type == EAGER) { | 421 if (type == EAGER) { |
416 ASSERT(from == NULL); | 422 ASSERT(from == NULL); |
417 optimized_code_ = function_->code(); | 423 compiled_code_ = function_->code(); |
418 if (FLAG_trace_deopt && FLAG_code_comments) { | 424 if (FLAG_trace_deopt && FLAG_code_comments) { |
419 // Print instruction associated with this bailout. | 425 // Print instruction associated with this bailout. |
420 const char* last_comment = NULL; | 426 const char* last_comment = NULL; |
421 int mask = RelocInfo::ModeMask(RelocInfo::COMMENT) | 427 int mask = RelocInfo::ModeMask(RelocInfo::COMMENT) |
422 | RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY); | 428 | RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY); |
423 for (RelocIterator it(optimized_code_, mask); !it.done(); it.next()) { | 429 for (RelocIterator it(compiled_code_, mask); !it.done(); it.next()) { |
424 RelocInfo* info = it.rinfo(); | 430 RelocInfo* info = it.rinfo(); |
425 if (info->rmode() == RelocInfo::COMMENT) { | 431 if (info->rmode() == RelocInfo::COMMENT) { |
426 last_comment = reinterpret_cast<const char*>(info->data()); | 432 last_comment = reinterpret_cast<const char*>(info->data()); |
427 } | 433 } |
428 if (info->rmode() == RelocInfo::RUNTIME_ENTRY) { | 434 if (info->rmode() == RelocInfo::RUNTIME_ENTRY) { |
429 unsigned id = Deoptimizer::GetDeoptimizationId( | 435 unsigned id = Deoptimizer::GetDeoptimizationId( |
430 info->target_address(), Deoptimizer::EAGER); | 436 info->target_address(), Deoptimizer::EAGER); |
431 if (id == bailout_id && last_comment != NULL) { | 437 if (id == bailout_id && last_comment != NULL) { |
432 PrintF(" %s\n", last_comment); | 438 PrintF(" %s\n", last_comment); |
433 break; | 439 break; |
434 } | 440 } |
435 } | 441 } |
436 } | 442 } |
437 } | 443 } |
438 } else if (type == LAZY) { | 444 } else if (type == LAZY) { |
439 optimized_code_ = FindDeoptimizingCodeFromAddress(from); | 445 compiled_code_ = FindDeoptimizingCodeFromAddress(from); |
440 ASSERT(optimized_code_ != NULL); | 446 if (compiled_code_ == NULL) { |
447 compiled_code_ = | |
448 static_cast<Code*>(isolate->heap()->FindCodeObject(from)); | |
449 } | |
450 ASSERT(compiled_code_ != NULL); | |
441 } else if (type == OSR) { | 451 } else if (type == OSR) { |
442 // The function has already been optimized and we're transitioning | 452 // The function has already been optimized and we're transitioning |
443 // from the unoptimized shared version to the optimized one in the | 453 // from the unoptimized shared version to the optimized one in the |
444 // function. The return address (from) points to unoptimized code. | 454 // function. The return address (from) points to unoptimized code. |
445 optimized_code_ = function_->code(); | 455 compiled_code_ = function_->code(); |
446 ASSERT(optimized_code_->kind() == Code::OPTIMIZED_FUNCTION); | 456 ASSERT(compiled_code_->kind() == Code::OPTIMIZED_FUNCTION); |
447 ASSERT(!optimized_code_->contains(from)); | 457 ASSERT(!compiled_code_->contains(from)); |
448 } else if (type == DEBUGGER) { | 458 } else if (type == DEBUGGER) { |
449 optimized_code_ = optimized_code; | 459 compiled_code_ = optimized_code; |
450 ASSERT(optimized_code_->contains(from)); | 460 ASSERT(compiled_code_->contains(from)); |
451 } | 461 } |
452 ASSERT(HEAP->allow_allocation(false)); | 462 ASSERT(HEAP->allow_allocation(false)); |
453 unsigned size = ComputeInputFrameSize(); | 463 unsigned size = ComputeInputFrameSize(); |
454 input_ = new(size) FrameDescription(size, function); | 464 input_ = new(size) FrameDescription(size, function); |
455 input_->SetFrameType(StackFrame::JAVA_SCRIPT); | 465 input_->SetFrameType(StackFrame::JAVA_SCRIPT); |
456 } | 466 } |
457 | 467 |
458 | 468 |
459 Deoptimizer::~Deoptimizer() { | 469 Deoptimizer::~Deoptimizer() { |
460 ASSERT(input_ == NULL && output_ == NULL); | 470 ASSERT(input_ == NULL && output_ == NULL); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
566 PrintF("[deoptimizing%s: begin 0x%08" V8PRIxPTR " ", | 576 PrintF("[deoptimizing%s: begin 0x%08" V8PRIxPTR " ", |
567 (bailout_type_ == LAZY ? " (lazy)" : ""), | 577 (bailout_type_ == LAZY ? " (lazy)" : ""), |
568 reinterpret_cast<intptr_t>(function_)); | 578 reinterpret_cast<intptr_t>(function_)); |
569 function_->PrintName(); | 579 function_->PrintName(); |
570 PrintF(" @%d]\n", bailout_id_); | 580 PrintF(" @%d]\n", bailout_id_); |
571 } | 581 } |
572 | 582 |
573 // Determine basic deoptimization information. The optimized frame is | 583 // Determine basic deoptimization information. The optimized frame is |
574 // described by the input data. | 584 // described by the input data. |
575 DeoptimizationInputData* input_data = | 585 DeoptimizationInputData* input_data = |
576 DeoptimizationInputData::cast(optimized_code_->deoptimization_data()); | 586 DeoptimizationInputData::cast(compiled_code_->deoptimization_data()); |
577 BailoutId node_id = input_data->AstId(bailout_id_); | 587 BailoutId node_id = input_data->AstId(bailout_id_); |
578 ByteArray* translations = input_data->TranslationByteArray(); | 588 ByteArray* translations = input_data->TranslationByteArray(); |
579 unsigned translation_index = | 589 unsigned translation_index = |
580 input_data->TranslationIndex(bailout_id_)->value(); | 590 input_data->TranslationIndex(bailout_id_)->value(); |
581 | 591 |
582 // Do the input frame to output frame(s) translation. | 592 // Do the input frame to output frame(s) translation. |
583 TranslationIterator iterator(translations, translation_index); | 593 TranslationIterator iterator(translations, translation_index); |
584 Translation::Opcode opcode = | 594 Translation::Opcode opcode = |
585 static_cast<Translation::Opcode>(iterator.Next()); | 595 static_cast<Translation::Opcode>(iterator.Next()); |
586 ASSERT(Translation::BEGIN == opcode); | 596 ASSERT(Translation::BEGIN == opcode); |
(...skipping 24 matching lines...) Expand all Loading... | |
611 break; | 621 break; |
612 case Translation::CONSTRUCT_STUB_FRAME: | 622 case Translation::CONSTRUCT_STUB_FRAME: |
613 DoComputeConstructStubFrame(&iterator, i); | 623 DoComputeConstructStubFrame(&iterator, i); |
614 break; | 624 break; |
615 case Translation::GETTER_STUB_FRAME: | 625 case Translation::GETTER_STUB_FRAME: |
616 DoComputeAccessorStubFrame(&iterator, i, false); | 626 DoComputeAccessorStubFrame(&iterator, i, false); |
617 break; | 627 break; |
618 case Translation::SETTER_STUB_FRAME: | 628 case Translation::SETTER_STUB_FRAME: |
619 DoComputeAccessorStubFrame(&iterator, i, true); | 629 DoComputeAccessorStubFrame(&iterator, i, true); |
620 break; | 630 break; |
631 case Translation::COMPILED_STUB_FRAME: | |
632 DoCompiledStubFrame(&iterator, i); | |
633 break; | |
621 case Translation::BEGIN: | 634 case Translation::BEGIN: |
622 case Translation::REGISTER: | 635 case Translation::REGISTER: |
623 case Translation::INT32_REGISTER: | 636 case Translation::INT32_REGISTER: |
624 case Translation::UINT32_REGISTER: | 637 case Translation::UINT32_REGISTER: |
625 case Translation::DOUBLE_REGISTER: | 638 case Translation::DOUBLE_REGISTER: |
626 case Translation::STACK_SLOT: | 639 case Translation::STACK_SLOT: |
627 case Translation::INT32_STACK_SLOT: | 640 case Translation::INT32_STACK_SLOT: |
628 case Translation::UINT32_STACK_SLOT: | 641 case Translation::UINT32_STACK_SLOT: |
629 case Translation::DOUBLE_STACK_SLOT: | 642 case Translation::DOUBLE_STACK_SLOT: |
630 case Translation::LITERAL: | 643 case Translation::LITERAL: |
631 case Translation::ARGUMENTS_OBJECT: | 644 case Translation::ARGUMENTS_OBJECT: |
632 case Translation::DUPLICATE: | 645 case Translation::DUPLICATE: |
646 default: | |
633 UNREACHABLE(); | 647 UNREACHABLE(); |
634 break; | 648 break; |
635 } | 649 } |
636 } | 650 } |
637 | 651 |
638 // Print some helpful diagnostic information. | 652 // Print some helpful diagnostic information. |
639 if (FLAG_trace_deopt) { | 653 if (FLAG_trace_deopt) { |
640 double ms = static_cast<double>(OS::Ticks() - start) / 1000; | 654 double ms = static_cast<double>(OS::Ticks() - start) / 1000; |
641 int index = output_count_ - 1; // Index of the topmost frame. | 655 int index = output_count_ - 1; // Index of the topmost frame. |
642 JSFunction* function = output_[index]->GetFunction(); | 656 JSFunction* function = output_[index]->GetFunction(); |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
802 opcode = static_cast<Translation::Opcode>(iterator->Next()); | 816 opcode = static_cast<Translation::Opcode>(iterator->Next()); |
803 } | 817 } |
804 | 818 |
805 switch (opcode) { | 819 switch (opcode) { |
806 case Translation::BEGIN: | 820 case Translation::BEGIN: |
807 case Translation::JS_FRAME: | 821 case Translation::JS_FRAME: |
808 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 822 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
809 case Translation::CONSTRUCT_STUB_FRAME: | 823 case Translation::CONSTRUCT_STUB_FRAME: |
810 case Translation::GETTER_STUB_FRAME: | 824 case Translation::GETTER_STUB_FRAME: |
811 case Translation::SETTER_STUB_FRAME: | 825 case Translation::SETTER_STUB_FRAME: |
826 case Translation::COMPILED_STUB_FRAME: | |
812 case Translation::DUPLICATE: | 827 case Translation::DUPLICATE: |
813 UNREACHABLE(); | 828 UNREACHABLE(); |
814 return; | 829 return; |
815 | 830 |
816 case Translation::REGISTER: { | 831 case Translation::REGISTER: { |
817 int input_reg = iterator->Next(); | 832 int input_reg = iterator->Next(); |
818 intptr_t input_value = input_->GetRegister(input_reg); | 833 intptr_t input_value = input_->GetRegister(input_reg); |
819 if (FLAG_trace_deopt) { | 834 if (FLAG_trace_deopt) { |
820 PrintF( | 835 PrintF( |
821 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ", | 836 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ", |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1110 opcode = static_cast<Translation::Opcode>(iterator->Next()); | 1125 opcode = static_cast<Translation::Opcode>(iterator->Next()); |
1111 } | 1126 } |
1112 | 1127 |
1113 switch (opcode) { | 1128 switch (opcode) { |
1114 case Translation::BEGIN: | 1129 case Translation::BEGIN: |
1115 case Translation::JS_FRAME: | 1130 case Translation::JS_FRAME: |
1116 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 1131 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
1117 case Translation::CONSTRUCT_STUB_FRAME: | 1132 case Translation::CONSTRUCT_STUB_FRAME: |
1118 case Translation::GETTER_STUB_FRAME: | 1133 case Translation::GETTER_STUB_FRAME: |
1119 case Translation::SETTER_STUB_FRAME: | 1134 case Translation::SETTER_STUB_FRAME: |
1135 case Translation::COMPILED_STUB_FRAME: | |
1120 case Translation::DUPLICATE: | 1136 case Translation::DUPLICATE: |
1121 UNREACHABLE(); // Malformed input. | 1137 UNREACHABLE(); // Malformed input. |
1122 return false; | 1138 return false; |
1123 | 1139 |
1124 case Translation::REGISTER: { | 1140 case Translation::REGISTER: { |
1125 int output_reg = iterator->Next(); | 1141 int output_reg = iterator->Next(); |
1126 if (FLAG_trace_osr) { | 1142 if (FLAG_trace_osr) { |
1127 PrintF(" %s <- 0x%08" V8PRIxPTR " ; [sp + %d]\n", | 1143 PrintF(" %s <- 0x%08" V8PRIxPTR " ; [sp + %d]\n", |
1128 converter.NameOfCPURegister(output_reg), | 1144 converter.NameOfCPURegister(output_reg), |
1129 input_value, | 1145 input_value, |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1330 // The fp-to-sp delta already takes the context and the function | 1346 // The fp-to-sp delta already takes the context and the function |
1331 // into account so we have to avoid double counting them (-2). | 1347 // into account so we have to avoid double counting them (-2). |
1332 unsigned result = fixed_size + fp_to_sp_delta_ - (2 * kPointerSize); | 1348 unsigned result = fixed_size + fp_to_sp_delta_ - (2 * kPointerSize); |
1333 #ifdef DEBUG | 1349 #ifdef DEBUG |
1334 if (bailout_type_ == OSR) { | 1350 if (bailout_type_ == OSR) { |
1335 // TODO(kasperl): It would be nice if we could verify that the | 1351 // TODO(kasperl): It would be nice if we could verify that the |
1336 // size matches with the stack height we can compute based on the | 1352 // size matches with the stack height we can compute based on the |
1337 // environment at the OSR entry. The code for that his built into | 1353 // environment at the OSR entry. The code for that his built into |
1338 // the DoComputeOsrOutputFrame function for now. | 1354 // the DoComputeOsrOutputFrame function for now. |
1339 } else { | 1355 } else { |
1340 unsigned stack_slots = optimized_code_->stack_slots(); | 1356 unsigned stack_slots = compiled_code_->stack_slots(); |
1341 unsigned outgoing_size = ComputeOutgoingArgumentSize(); | 1357 unsigned outgoing_size = compiled_code_->kind() == Code::COMPILED_STUB |
1358 ? 0 : ComputeOutgoingArgumentSize(); | |
1342 ASSERT(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size); | 1359 ASSERT(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size); |
1343 } | 1360 } |
1344 #endif | 1361 #endif |
1345 return result; | 1362 return result; |
1346 } | 1363 } |
1347 | 1364 |
1348 | 1365 |
1349 unsigned Deoptimizer::ComputeFixedSize(JSFunction* function) const { | 1366 unsigned Deoptimizer::ComputeFixedSize(JSFunction* function) const { |
1350 // The fixed part of the frame consists of the return address, frame | 1367 // The fixed part of the frame consists of the return address, frame |
1351 // pointer, function, context, and all the incoming arguments. | 1368 // pointer, function, context, and all the incoming arguments. |
1352 return ComputeIncomingArgumentSize(function) + | 1369 return ComputeIncomingArgumentSize(function) + |
1353 StandardFrameConstants::kFixedFrameSize; | 1370 StandardFrameConstants::kFixedFrameSize; |
1354 } | 1371 } |
1355 | 1372 |
1356 | 1373 |
1357 unsigned Deoptimizer::ComputeIncomingArgumentSize(JSFunction* function) const { | 1374 unsigned Deoptimizer::ComputeIncomingArgumentSize(JSFunction* function) const { |
1358 // The incoming arguments is the values for formal parameters and | 1375 // The incoming arguments is the values for formal parameters and |
1359 // the receiver. Every slot contains a pointer. | 1376 // the receiver. Every slot contains a pointer. |
1377 if (function->IsSmi()) { | |
1378 ASSERT(Smi::cast(function) == Smi::FromInt(StackFrame::STUB)); | |
1379 return 0; | |
1380 } | |
1360 unsigned arguments = function->shared()->formal_parameter_count() + 1; | 1381 unsigned arguments = function->shared()->formal_parameter_count() + 1; |
1361 return arguments * kPointerSize; | 1382 return arguments * kPointerSize; |
1362 } | 1383 } |
1363 | 1384 |
1364 | 1385 |
1365 unsigned Deoptimizer::ComputeOutgoingArgumentSize() const { | 1386 unsigned Deoptimizer::ComputeOutgoingArgumentSize() const { |
1366 DeoptimizationInputData* data = DeoptimizationInputData::cast( | 1387 DeoptimizationInputData* data = DeoptimizationInputData::cast( |
1367 optimized_code_->deoptimization_data()); | 1388 compiled_code_->deoptimization_data()); |
1368 unsigned height = data->ArgumentsStackHeight(bailout_id_)->value(); | 1389 unsigned height = data->ArgumentsStackHeight(bailout_id_)->value(); |
1369 return height * kPointerSize; | 1390 return height * kPointerSize; |
1370 } | 1391 } |
1371 | 1392 |
1372 | 1393 |
1373 Object* Deoptimizer::ComputeLiteral(int index) const { | 1394 Object* Deoptimizer::ComputeLiteral(int index) const { |
1374 DeoptimizationInputData* data = DeoptimizationInputData::cast( | 1395 DeoptimizationInputData* data = DeoptimizationInputData::cast( |
1375 optimized_code_->deoptimization_data()); | 1396 compiled_code_->deoptimization_data()); |
1376 FixedArray* literals = data->LiteralArray(); | 1397 FixedArray* literals = data->LiteralArray(); |
1377 return literals->get(index); | 1398 return literals->get(index); |
1378 } | 1399 } |
1379 | 1400 |
1380 | 1401 |
1381 void Deoptimizer::AddArgumentsObject(intptr_t slot_address, int argc) { | 1402 void Deoptimizer::AddArgumentsObject(intptr_t slot_address, int argc) { |
1382 ArgumentsObjectMaterializationDescriptor object_desc( | 1403 ArgumentsObjectMaterializationDescriptor object_desc( |
1383 reinterpret_cast<Address>(slot_address), argc); | 1404 reinterpret_cast<Address>(slot_address), argc); |
1384 deferred_arguments_objects_.Add(object_desc); | 1405 deferred_arguments_objects_.Add(object_desc); |
1385 } | 1406 } |
(...skipping 10 matching lines...) Expand all Loading... | |
1396 deferred_heap_numbers_.Add(value_desc); | 1417 deferred_heap_numbers_.Add(value_desc); |
1397 } | 1418 } |
1398 | 1419 |
1399 | 1420 |
1400 void Deoptimizer::EnsureCodeForDeoptimizationEntry(BailoutType type, | 1421 void Deoptimizer::EnsureCodeForDeoptimizationEntry(BailoutType type, |
1401 int max_entry_id) { | 1422 int max_entry_id) { |
1402 // We cannot run this if the serializer is enabled because this will | 1423 // We cannot run this if the serializer is enabled because this will |
1403 // cause us to emit relocation information for the external | 1424 // cause us to emit relocation information for the external |
1404 // references. This is fine because the deoptimizer's code section | 1425 // references. This is fine because the deoptimizer's code section |
1405 // isn't meant to be serialized at all. | 1426 // isn't meant to be serialized at all. |
1406 ASSERT(!Serializer::enabled()); | |
1407 | |
1408 ASSERT(type == EAGER || type == LAZY); | 1427 ASSERT(type == EAGER || type == LAZY); |
1409 DeoptimizerData* data = Isolate::Current()->deoptimizer_data(); | 1428 DeoptimizerData* data = Isolate::Current()->deoptimizer_data(); |
1410 int entry_count = (type == EAGER) | 1429 int entry_count = (type == EAGER) |
1411 ? data->eager_deoptimization_entry_code_entries_ | 1430 ? data->eager_deoptimization_entry_code_entries_ |
1412 : data->lazy_deoptimization_entry_code_entries_; | 1431 : data->lazy_deoptimization_entry_code_entries_; |
1413 if (max_entry_id < entry_count) return; | 1432 if (max_entry_id < entry_count) return; |
1414 entry_count = Min(Max(entry_count * 2, Deoptimizer::kMinNumberOfEntries), | 1433 entry_count = Min(Max(entry_count * 2, Deoptimizer::kMinNumberOfEntries), |
1415 Deoptimizer::kMaxNumberOfEntries); | 1434 Deoptimizer::kMaxNumberOfEntries); |
1416 | 1435 |
1417 MacroAssembler masm(Isolate::Current(), NULL, 16 * KB); | 1436 MacroAssembler masm(Isolate::Current(), NULL, 16 * KB); |
1418 masm.set_emit_debug_code(false); | 1437 masm.set_emit_debug_code(false); |
1419 GenerateDeoptimizationEntries(&masm, entry_count, type); | 1438 GenerateDeoptimizationEntries(&masm, entry_count, type); |
1420 CodeDesc desc; | 1439 CodeDesc desc; |
1421 masm.GetCode(&desc); | 1440 masm.GetCode(&desc); |
1422 ASSERT(desc.reloc_size == 0); | |
1423 | 1441 |
1424 VirtualMemory* memory = type == EAGER | 1442 VirtualMemory* memory = type == EAGER |
1425 ? data->eager_deoptimization_entry_code_ | 1443 ? data->eager_deoptimization_entry_code_ |
1426 : data->lazy_deoptimization_entry_code_; | 1444 : data->lazy_deoptimization_entry_code_; |
1427 size_t table_size = Deoptimizer::GetMaxDeoptTableSize(); | 1445 size_t table_size = Deoptimizer::GetMaxDeoptTableSize(); |
1428 ASSERT(static_cast<int>(table_size) >= desc.instr_size); | 1446 ASSERT(static_cast<int>(table_size) >= desc.instr_size); |
1429 memory->Commit(memory->address(), table_size, true); | 1447 memory->Commit(memory->address(), table_size, true); |
1430 memcpy(memory->address(), desc.buffer, desc.instr_size); | 1448 memcpy(memory->address(), desc.buffer, desc.instr_size); |
1431 CPU::FlushICache(memory->address(), desc.instr_size); | 1449 CPU::FlushICache(memory->address(), desc.instr_size); |
1432 | 1450 |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1674 void Translation::BeginJSFrame(BailoutId node_id, | 1692 void Translation::BeginJSFrame(BailoutId node_id, |
1675 int literal_id, | 1693 int literal_id, |
1676 unsigned height) { | 1694 unsigned height) { |
1677 buffer_->Add(JS_FRAME, zone()); | 1695 buffer_->Add(JS_FRAME, zone()); |
1678 buffer_->Add(node_id.ToInt(), zone()); | 1696 buffer_->Add(node_id.ToInt(), zone()); |
1679 buffer_->Add(literal_id, zone()); | 1697 buffer_->Add(literal_id, zone()); |
1680 buffer_->Add(height, zone()); | 1698 buffer_->Add(height, zone()); |
1681 } | 1699 } |
1682 | 1700 |
1683 | 1701 |
1702 void Translation::BeginCompiledStubFrame() { | |
1703 buffer_->Add(COMPILED_STUB_FRAME, zone()); | |
1704 } | |
1705 | |
1706 | |
1684 void Translation::StoreRegister(Register reg) { | 1707 void Translation::StoreRegister(Register reg) { |
1685 buffer_->Add(REGISTER, zone()); | 1708 buffer_->Add(REGISTER, zone()); |
1686 buffer_->Add(reg.code(), zone()); | 1709 buffer_->Add(reg.code(), zone()); |
1687 } | 1710 } |
1688 | 1711 |
1689 | 1712 |
1690 void Translation::StoreInt32Register(Register reg) { | 1713 void Translation::StoreInt32Register(Register reg) { |
1691 buffer_->Add(INT32_REGISTER, zone()); | 1714 buffer_->Add(INT32_REGISTER, zone()); |
1692 buffer_->Add(reg.code(), zone()); | 1715 buffer_->Add(reg.code(), zone()); |
1693 } | 1716 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1755 case SETTER_STUB_FRAME: | 1778 case SETTER_STUB_FRAME: |
1756 case REGISTER: | 1779 case REGISTER: |
1757 case INT32_REGISTER: | 1780 case INT32_REGISTER: |
1758 case UINT32_REGISTER: | 1781 case UINT32_REGISTER: |
1759 case DOUBLE_REGISTER: | 1782 case DOUBLE_REGISTER: |
1760 case STACK_SLOT: | 1783 case STACK_SLOT: |
1761 case INT32_STACK_SLOT: | 1784 case INT32_STACK_SLOT: |
1762 case UINT32_STACK_SLOT: | 1785 case UINT32_STACK_SLOT: |
1763 case DOUBLE_STACK_SLOT: | 1786 case DOUBLE_STACK_SLOT: |
1764 case LITERAL: | 1787 case LITERAL: |
1788 case COMPILED_STUB_FRAME: | |
1765 return 1; | 1789 return 1; |
1766 case BEGIN: | 1790 case BEGIN: |
1767 case ARGUMENTS_ADAPTOR_FRAME: | 1791 case ARGUMENTS_ADAPTOR_FRAME: |
1768 case CONSTRUCT_STUB_FRAME: | 1792 case CONSTRUCT_STUB_FRAME: |
1769 case ARGUMENTS_OBJECT: | 1793 case ARGUMENTS_OBJECT: |
1770 return 2; | 1794 return 2; |
1771 case JS_FRAME: | 1795 case JS_FRAME: |
1772 return 3; | 1796 return 3; |
1773 } | 1797 } |
1774 UNREACHABLE(); | 1798 UNREACHABLE(); |
(...skipping 10 matching lines...) Expand all Loading... | |
1785 case JS_FRAME: | 1809 case JS_FRAME: |
1786 return "JS_FRAME"; | 1810 return "JS_FRAME"; |
1787 case ARGUMENTS_ADAPTOR_FRAME: | 1811 case ARGUMENTS_ADAPTOR_FRAME: |
1788 return "ARGUMENTS_ADAPTOR_FRAME"; | 1812 return "ARGUMENTS_ADAPTOR_FRAME"; |
1789 case CONSTRUCT_STUB_FRAME: | 1813 case CONSTRUCT_STUB_FRAME: |
1790 return "CONSTRUCT_STUB_FRAME"; | 1814 return "CONSTRUCT_STUB_FRAME"; |
1791 case GETTER_STUB_FRAME: | 1815 case GETTER_STUB_FRAME: |
1792 return "GETTER_STUB_FRAME"; | 1816 return "GETTER_STUB_FRAME"; |
1793 case SETTER_STUB_FRAME: | 1817 case SETTER_STUB_FRAME: |
1794 return "SETTER_STUB_FRAME"; | 1818 return "SETTER_STUB_FRAME"; |
1819 case COMPILED_STUB_FRAME: | |
1820 return "COMPILED_STUB_FRAME"; | |
1795 case REGISTER: | 1821 case REGISTER: |
1796 return "REGISTER"; | 1822 return "REGISTER"; |
1797 case INT32_REGISTER: | 1823 case INT32_REGISTER: |
1798 return "INT32_REGISTER"; | 1824 return "INT32_REGISTER"; |
1799 case UINT32_REGISTER: | 1825 case UINT32_REGISTER: |
1800 return "UINT32_REGISTER"; | 1826 return "UINT32_REGISTER"; |
1801 case DOUBLE_REGISTER: | 1827 case DOUBLE_REGISTER: |
1802 return "DOUBLE_REGISTER"; | 1828 return "DOUBLE_REGISTER"; |
1803 case STACK_SLOT: | 1829 case STACK_SLOT: |
1804 return "STACK_SLOT"; | 1830 return "STACK_SLOT"; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1892 case Translation::DOUBLE_STACK_SLOT: { | 1918 case Translation::DOUBLE_STACK_SLOT: { |
1893 int slot_index = iterator->Next(); | 1919 int slot_index = iterator->Next(); |
1894 Address slot_addr = SlotAddress(frame, slot_index); | 1920 Address slot_addr = SlotAddress(frame, slot_index); |
1895 return SlotRef(slot_addr, SlotRef::DOUBLE); | 1921 return SlotRef(slot_addr, SlotRef::DOUBLE); |
1896 } | 1922 } |
1897 | 1923 |
1898 case Translation::LITERAL: { | 1924 case Translation::LITERAL: { |
1899 int literal_index = iterator->Next(); | 1925 int literal_index = iterator->Next(); |
1900 return SlotRef(data->LiteralArray()->get(literal_index)); | 1926 return SlotRef(data->LiteralArray()->get(literal_index)); |
1901 } | 1927 } |
1928 | |
1929 case Translation::COMPILED_STUB_FRAME: | |
1930 UNREACHABLE(); | |
1931 break; | |
1902 } | 1932 } |
1903 | 1933 |
1904 UNREACHABLE(); | 1934 UNREACHABLE(); |
1905 return SlotRef(); | 1935 return SlotRef(); |
1906 } | 1936 } |
1907 | 1937 |
1908 | 1938 |
1909 void SlotRef::ComputeSlotsForArguments(Vector<SlotRef>* args_slots, | 1939 void SlotRef::ComputeSlotsForArguments(Vector<SlotRef>* args_slots, |
1910 TranslationIterator* it, | 1940 TranslationIterator* it, |
1911 DeoptimizationInputData* data, | 1941 DeoptimizationInputData* data, |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2022 | 2052 |
2023 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { | 2053 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { |
2024 v->VisitPointer(BitCast<Object**>(&function_)); | 2054 v->VisitPointer(BitCast<Object**>(&function_)); |
2025 v->VisitPointers(parameters_, parameters_ + parameters_count_); | 2055 v->VisitPointers(parameters_, parameters_ + parameters_count_); |
2026 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); | 2056 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); |
2027 } | 2057 } |
2028 | 2058 |
2029 #endif // ENABLE_DEBUGGER_SUPPORT | 2059 #endif // ENABLE_DEBUGGER_SUPPORT |
2030 | 2060 |
2031 } } // namespace v8::internal | 2061 } } // namespace v8::internal |
OLD | NEW |