| 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 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 ASSERT_LT(jsframe_index, deoptimizer->jsframe_count()); | 163 ASSERT_LT(jsframe_index, deoptimizer->jsframe_count()); |
| 164 | 164 |
| 165 // Convert JS frame index into frame index. | 165 // Convert JS frame index into frame index. |
| 166 int frame_index = deoptimizer->ConvertJSFrameIndexToFrameIndex(jsframe_index); | 166 int frame_index = deoptimizer->ConvertJSFrameIndexToFrameIndex(jsframe_index); |
| 167 | 167 |
| 168 bool has_arguments_adaptor = | 168 bool has_arguments_adaptor = |
| 169 frame_index > 0 && | 169 frame_index > 0 && |
| 170 deoptimizer->output_[frame_index - 1]->GetFrameType() == | 170 deoptimizer->output_[frame_index - 1]->GetFrameType() == |
| 171 StackFrame::ARGUMENTS_ADAPTOR; | 171 StackFrame::ARGUMENTS_ADAPTOR; |
| 172 | 172 |
| 173 DeoptimizedFrameInfo* info = | 173 int construct_offset = has_arguments_adaptor ? 2 : 1; |
| 174 new DeoptimizedFrameInfo(deoptimizer, frame_index, has_arguments_adaptor); | 174 bool has_construct_stub = |
| 175 frame_index >= construct_offset && |
| 176 deoptimizer->output_[frame_index - construct_offset]->GetFrameType() == |
| 177 StackFrame::CONSTRUCT; |
| 178 |
| 179 DeoptimizedFrameInfo* info = new DeoptimizedFrameInfo(deoptimizer, |
| 180 frame_index, |
| 181 has_arguments_adaptor, |
| 182 has_construct_stub); |
| 175 isolate->deoptimizer_data()->deoptimized_frame_info_ = info; | 183 isolate->deoptimizer_data()->deoptimized_frame_info_ = info; |
| 176 | 184 |
| 177 // Get the "simulated" top and size for the requested frame. | 185 // Get the "simulated" top and size for the requested frame. |
| 178 FrameDescription* parameters_frame = | 186 FrameDescription* parameters_frame = |
| 179 deoptimizer->output_[ | 187 deoptimizer->output_[ |
| 180 has_arguments_adaptor ? (frame_index - 1) : frame_index]; | 188 has_arguments_adaptor ? (frame_index - 1) : frame_index]; |
| 181 | 189 |
| 182 uint32_t parameters_size = (info->parameters_count() + 1) * kPointerSize; | 190 uint32_t parameters_size = (info->parameters_count() + 1) * kPointerSize; |
| 183 Address parameters_top = reinterpret_cast<Address>( | 191 Address parameters_top = reinterpret_cast<Address>( |
| 184 parameters_frame->GetTop() + (parameters_frame->GetFrameSize() - | 192 parameters_frame->GetTop() + (parameters_frame->GetFrameSize() - |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 Translation::Opcode opcode = | 571 Translation::Opcode opcode = |
| 564 static_cast<Translation::Opcode>(iterator.Next()); | 572 static_cast<Translation::Opcode>(iterator.Next()); |
| 565 switch (opcode) { | 573 switch (opcode) { |
| 566 case Translation::JS_FRAME: | 574 case Translation::JS_FRAME: |
| 567 DoComputeJSFrame(&iterator, i); | 575 DoComputeJSFrame(&iterator, i); |
| 568 jsframe_count_++; | 576 jsframe_count_++; |
| 569 break; | 577 break; |
| 570 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 578 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
| 571 DoComputeArgumentsAdaptorFrame(&iterator, i); | 579 DoComputeArgumentsAdaptorFrame(&iterator, i); |
| 572 break; | 580 break; |
| 581 case Translation::CONSTRUCT_STUB_FRAME: |
| 582 DoComputeConstructStubFrame(&iterator, i); |
| 583 break; |
| 573 default: | 584 default: |
| 574 UNREACHABLE(); | 585 UNREACHABLE(); |
| 575 break; | 586 break; |
| 576 } | 587 } |
| 577 } | 588 } |
| 578 | 589 |
| 579 // Print some helpful diagnostic information. | 590 // Print some helpful diagnostic information. |
| 580 if (FLAG_trace_deopt) { | 591 if (FLAG_trace_deopt) { |
| 581 double ms = static_cast<double>(OS::Ticks() - start) / 1000; | 592 double ms = static_cast<double>(OS::Ticks() - start) / 1000; |
| 582 int index = output_count_ - 1; // Index of the topmost frame. | 593 int index = output_count_ - 1; // Index of the topmost frame. |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 while (opcode == Translation::DUPLICATE) { | 690 while (opcode == Translation::DUPLICATE) { |
| 680 opcode = static_cast<Translation::Opcode>(iterator->Next()); | 691 opcode = static_cast<Translation::Opcode>(iterator->Next()); |
| 681 iterator->Skip(Translation::NumberOfOperandsFor(opcode)); | 692 iterator->Skip(Translation::NumberOfOperandsFor(opcode)); |
| 682 opcode = static_cast<Translation::Opcode>(iterator->Next()); | 693 opcode = static_cast<Translation::Opcode>(iterator->Next()); |
| 683 } | 694 } |
| 684 | 695 |
| 685 switch (opcode) { | 696 switch (opcode) { |
| 686 case Translation::BEGIN: | 697 case Translation::BEGIN: |
| 687 case Translation::JS_FRAME: | 698 case Translation::JS_FRAME: |
| 688 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 699 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
| 700 case Translation::CONSTRUCT_STUB_FRAME: |
| 689 case Translation::DUPLICATE: | 701 case Translation::DUPLICATE: |
| 690 UNREACHABLE(); | 702 UNREACHABLE(); |
| 691 return; | 703 return; |
| 692 | 704 |
| 693 case Translation::REGISTER: { | 705 case Translation::REGISTER: { |
| 694 int input_reg = iterator->Next(); | 706 int input_reg = iterator->Next(); |
| 695 intptr_t input_value = input_->GetRegister(input_reg); | 707 intptr_t input_value = input_->GetRegister(input_reg); |
| 696 if (FLAG_trace_deopt) { | 708 if (FLAG_trace_deopt) { |
| 697 PrintF( | 709 PrintF( |
| 698 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ", | 710 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ", |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 866 static_cast<Translation::Opcode>(iterator->Next()); | 878 static_cast<Translation::Opcode>(iterator->Next()); |
| 867 bool duplicate = (opcode == Translation::DUPLICATE); | 879 bool duplicate = (opcode == Translation::DUPLICATE); |
| 868 if (duplicate) { | 880 if (duplicate) { |
| 869 opcode = static_cast<Translation::Opcode>(iterator->Next()); | 881 opcode = static_cast<Translation::Opcode>(iterator->Next()); |
| 870 } | 882 } |
| 871 | 883 |
| 872 switch (opcode) { | 884 switch (opcode) { |
| 873 case Translation::BEGIN: | 885 case Translation::BEGIN: |
| 874 case Translation::JS_FRAME: | 886 case Translation::JS_FRAME: |
| 875 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 887 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
| 888 case Translation::CONSTRUCT_STUB_FRAME: |
| 876 case Translation::DUPLICATE: | 889 case Translation::DUPLICATE: |
| 877 UNREACHABLE(); // Malformed input. | 890 UNREACHABLE(); // Malformed input. |
| 878 return false; | 891 return false; |
| 879 | 892 |
| 880 case Translation::REGISTER: { | 893 case Translation::REGISTER: { |
| 881 int output_reg = iterator->Next(); | 894 int output_reg = iterator->Next(); |
| 882 if (FLAG_trace_osr) { | 895 if (FLAG_trace_osr) { |
| 883 PrintF(" %s <- 0x%08" V8PRIxPTR " ; [sp + %d]\n", | 896 PrintF(" %s <- 0x%08" V8PRIxPTR " ; [sp + %d]\n", |
| 884 converter.NameOfCPURegister(output_reg), | 897 converter.NameOfCPURegister(output_reg), |
| 885 input_value, | 898 input_value, |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1198 UNREACHABLE(); | 1211 UNREACHABLE(); |
| 1199 } | 1212 } |
| 1200 | 1213 |
| 1201 | 1214 |
| 1202 FrameDescription::FrameDescription(uint32_t frame_size, | 1215 FrameDescription::FrameDescription(uint32_t frame_size, |
| 1203 JSFunction* function) | 1216 JSFunction* function) |
| 1204 : frame_size_(frame_size), | 1217 : frame_size_(frame_size), |
| 1205 function_(function), | 1218 function_(function), |
| 1206 top_(kZapUint32), | 1219 top_(kZapUint32), |
| 1207 pc_(kZapUint32), | 1220 pc_(kZapUint32), |
| 1208 fp_(kZapUint32) { | 1221 fp_(kZapUint32), |
| 1222 context_(kZapUint32) { |
| 1209 // Zap all the registers. | 1223 // Zap all the registers. |
| 1210 for (int r = 0; r < Register::kNumRegisters; r++) { | 1224 for (int r = 0; r < Register::kNumRegisters; r++) { |
| 1211 SetRegister(r, kZapUint32); | 1225 SetRegister(r, kZapUint32); |
| 1212 } | 1226 } |
| 1213 | 1227 |
| 1214 // Zap all the slots. | 1228 // Zap all the slots. |
| 1215 for (unsigned o = 0; o < frame_size; o += kPointerSize) { | 1229 for (unsigned o = 0; o < frame_size; o += kPointerSize) { |
| 1216 SetFrameSlot(o, kZapUint32); | 1230 SetFrameSlot(o, kZapUint32); |
| 1217 } | 1231 } |
| 1218 } | 1232 } |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1312 | 1326 |
| 1313 Handle<ByteArray> TranslationBuffer::CreateByteArray() { | 1327 Handle<ByteArray> TranslationBuffer::CreateByteArray() { |
| 1314 int length = contents_.length(); | 1328 int length = contents_.length(); |
| 1315 Handle<ByteArray> result = | 1329 Handle<ByteArray> result = |
| 1316 Isolate::Current()->factory()->NewByteArray(length, TENURED); | 1330 Isolate::Current()->factory()->NewByteArray(length, TENURED); |
| 1317 memcpy(result->GetDataStartAddress(), contents_.ToVector().start(), length); | 1331 memcpy(result->GetDataStartAddress(), contents_.ToVector().start(), length); |
| 1318 return result; | 1332 return result; |
| 1319 } | 1333 } |
| 1320 | 1334 |
| 1321 | 1335 |
| 1336 void Translation::BeginConstructStubFrame(int literal_id, unsigned height) { |
| 1337 buffer_->Add(CONSTRUCT_STUB_FRAME); |
| 1338 buffer_->Add(literal_id); |
| 1339 buffer_->Add(height); |
| 1340 } |
| 1341 |
| 1342 |
| 1322 void Translation::BeginArgumentsAdaptorFrame(int literal_id, unsigned height) { | 1343 void Translation::BeginArgumentsAdaptorFrame(int literal_id, unsigned height) { |
| 1323 buffer_->Add(ARGUMENTS_ADAPTOR_FRAME); | 1344 buffer_->Add(ARGUMENTS_ADAPTOR_FRAME); |
| 1324 buffer_->Add(literal_id); | 1345 buffer_->Add(literal_id); |
| 1325 buffer_->Add(height); | 1346 buffer_->Add(height); |
| 1326 } | 1347 } |
| 1327 | 1348 |
| 1328 | 1349 |
| 1329 void Translation::BeginJSFrame(int node_id, int literal_id, unsigned height) { | 1350 void Translation::BeginJSFrame(int node_id, int literal_id, unsigned height) { |
| 1330 buffer_->Add(JS_FRAME); | 1351 buffer_->Add(JS_FRAME); |
| 1331 buffer_->Add(node_id); | 1352 buffer_->Add(node_id); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1394 case REGISTER: | 1415 case REGISTER: |
| 1395 case INT32_REGISTER: | 1416 case INT32_REGISTER: |
| 1396 case DOUBLE_REGISTER: | 1417 case DOUBLE_REGISTER: |
| 1397 case STACK_SLOT: | 1418 case STACK_SLOT: |
| 1398 case INT32_STACK_SLOT: | 1419 case INT32_STACK_SLOT: |
| 1399 case DOUBLE_STACK_SLOT: | 1420 case DOUBLE_STACK_SLOT: |
| 1400 case LITERAL: | 1421 case LITERAL: |
| 1401 return 1; | 1422 return 1; |
| 1402 case BEGIN: | 1423 case BEGIN: |
| 1403 case ARGUMENTS_ADAPTOR_FRAME: | 1424 case ARGUMENTS_ADAPTOR_FRAME: |
| 1425 case CONSTRUCT_STUB_FRAME: |
| 1404 return 2; | 1426 return 2; |
| 1405 case JS_FRAME: | 1427 case JS_FRAME: |
| 1406 return 3; | 1428 return 3; |
| 1407 } | 1429 } |
| 1408 UNREACHABLE(); | 1430 UNREACHABLE(); |
| 1409 return -1; | 1431 return -1; |
| 1410 } | 1432 } |
| 1411 | 1433 |
| 1412 | 1434 |
| 1413 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER) | 1435 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER) |
| 1414 | 1436 |
| 1415 const char* Translation::StringFor(Opcode opcode) { | 1437 const char* Translation::StringFor(Opcode opcode) { |
| 1416 switch (opcode) { | 1438 switch (opcode) { |
| 1417 case BEGIN: | 1439 case BEGIN: |
| 1418 return "BEGIN"; | 1440 return "BEGIN"; |
| 1419 case JS_FRAME: | 1441 case JS_FRAME: |
| 1420 return "JS_FRAME"; | 1442 return "JS_FRAME"; |
| 1421 case ARGUMENTS_ADAPTOR_FRAME: | 1443 case ARGUMENTS_ADAPTOR_FRAME: |
| 1422 return "ARGUMENTS_ADAPTOR_FRAME"; | 1444 return "ARGUMENTS_ADAPTOR_FRAME"; |
| 1445 case CONSTRUCT_STUB_FRAME: |
| 1446 return "CONSTRUCT_STUB_FRAME"; |
| 1423 case REGISTER: | 1447 case REGISTER: |
| 1424 return "REGISTER"; | 1448 return "REGISTER"; |
| 1425 case INT32_REGISTER: | 1449 case INT32_REGISTER: |
| 1426 return "INT32_REGISTER"; | 1450 return "INT32_REGISTER"; |
| 1427 case DOUBLE_REGISTER: | 1451 case DOUBLE_REGISTER: |
| 1428 return "DOUBLE_REGISTER"; | 1452 return "DOUBLE_REGISTER"; |
| 1429 case STACK_SLOT: | 1453 case STACK_SLOT: |
| 1430 return "STACK_SLOT"; | 1454 return "STACK_SLOT"; |
| 1431 case INT32_STACK_SLOT: | 1455 case INT32_STACK_SLOT: |
| 1432 return "INT32_STACK_SLOT"; | 1456 return "INT32_STACK_SLOT"; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1468 SlotRef SlotRef::ComputeSlotForNextArgument(TranslationIterator* iterator, | 1492 SlotRef SlotRef::ComputeSlotForNextArgument(TranslationIterator* iterator, |
| 1469 DeoptimizationInputData* data, | 1493 DeoptimizationInputData* data, |
| 1470 JavaScriptFrame* frame) { | 1494 JavaScriptFrame* frame) { |
| 1471 Translation::Opcode opcode = | 1495 Translation::Opcode opcode = |
| 1472 static_cast<Translation::Opcode>(iterator->Next()); | 1496 static_cast<Translation::Opcode>(iterator->Next()); |
| 1473 | 1497 |
| 1474 switch (opcode) { | 1498 switch (opcode) { |
| 1475 case Translation::BEGIN: | 1499 case Translation::BEGIN: |
| 1476 case Translation::JS_FRAME: | 1500 case Translation::JS_FRAME: |
| 1477 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 1501 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
| 1502 case Translation::CONSTRUCT_STUB_FRAME: |
| 1478 // Peeled off before getting here. | 1503 // Peeled off before getting here. |
| 1479 break; | 1504 break; |
| 1480 | 1505 |
| 1481 case Translation::ARGUMENTS_OBJECT: | 1506 case Translation::ARGUMENTS_OBJECT: |
| 1482 // This can be only emitted for local slots not for argument slots. | 1507 // This can be only emitted for local slots not for argument slots. |
| 1483 break; | 1508 break; |
| 1484 | 1509 |
| 1485 case Translation::REGISTER: | 1510 case Translation::REGISTER: |
| 1486 case Translation::INT32_REGISTER: | 1511 case Translation::INT32_REGISTER: |
| 1487 case Translation::DOUBLE_REGISTER: | 1512 case Translation::DOUBLE_REGISTER: |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1590 // Skip over operands to advance to the next opcode. | 1615 // Skip over operands to advance to the next opcode. |
| 1591 it.Skip(Translation::NumberOfOperandsFor(opcode)); | 1616 it.Skip(Translation::NumberOfOperandsFor(opcode)); |
| 1592 } | 1617 } |
| 1593 | 1618 |
| 1594 UNREACHABLE(); | 1619 UNREACHABLE(); |
| 1595 return Vector<SlotRef>(); | 1620 return Vector<SlotRef>(); |
| 1596 } | 1621 } |
| 1597 | 1622 |
| 1598 #ifdef ENABLE_DEBUGGER_SUPPORT | 1623 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 1599 | 1624 |
| 1600 DeoptimizedFrameInfo::DeoptimizedFrameInfo( | 1625 DeoptimizedFrameInfo::DeoptimizedFrameInfo(Deoptimizer* deoptimizer, |
| 1601 Deoptimizer* deoptimizer, int frame_index, bool has_arguments_adaptor) { | 1626 int frame_index, |
| 1627 bool has_arguments_adaptor, |
| 1628 bool has_construct_stub) { |
| 1602 FrameDescription* output_frame = deoptimizer->output_[frame_index]; | 1629 FrameDescription* output_frame = deoptimizer->output_[frame_index]; |
| 1603 SetFunction(output_frame->GetFunction()); | 1630 function_ = output_frame->GetFunction(); |
| 1631 has_construct_stub_ = has_construct_stub; |
| 1604 expression_count_ = output_frame->GetExpressionCount(); | 1632 expression_count_ = output_frame->GetExpressionCount(); |
| 1605 expression_stack_ = new Object*[expression_count_]; | 1633 expression_stack_ = new Object*[expression_count_]; |
| 1606 pc_ = output_frame->GetPc(); | 1634 pc_ = output_frame->GetPc(); |
| 1607 for (int i = 0; i < expression_count_; i++) { | 1635 for (int i = 0; i < expression_count_; i++) { |
| 1608 SetExpression(i, output_frame->GetExpression(i)); | 1636 SetExpression(i, output_frame->GetExpression(i)); |
| 1609 } | 1637 } |
| 1610 | 1638 |
| 1611 if (has_arguments_adaptor) { | 1639 if (has_arguments_adaptor) { |
| 1612 output_frame = deoptimizer->output_[frame_index - 1]; | 1640 output_frame = deoptimizer->output_[frame_index - 1]; |
| 1613 ASSERT(output_frame->GetFrameType() == StackFrame::ARGUMENTS_ADAPTOR); | 1641 ASSERT(output_frame->GetFrameType() == StackFrame::ARGUMENTS_ADAPTOR); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1628 | 1656 |
| 1629 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { | 1657 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { |
| 1630 v->VisitPointer(BitCast<Object**>(&function_)); | 1658 v->VisitPointer(BitCast<Object**>(&function_)); |
| 1631 v->VisitPointers(parameters_, parameters_ + parameters_count_); | 1659 v->VisitPointers(parameters_, parameters_ + parameters_count_); |
| 1632 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); | 1660 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); |
| 1633 } | 1661 } |
| 1634 | 1662 |
| 1635 #endif // ENABLE_DEBUGGER_SUPPORT | 1663 #endif // ENABLE_DEBUGGER_SUPPORT |
| 1636 | 1664 |
| 1637 } } // namespace v8::internal | 1665 } } // namespace v8::internal |
| OLD | NEW |