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