OLD | NEW |
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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/cpu-profiler.h" | 9 #include "src/cpu-profiler.h" |
10 #include "src/deoptimizer.h" | 10 #include "src/deoptimizer.h" |
(...skipping 1403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1414 // parameters in registers +-------------------------+ | 1414 // parameters in registers +-------------------------+ |
1415 // and spilled to stack | .... | | 1415 // and spilled to stack | .... | |
1416 // +-------------------------+ | 1416 // +-------------------------+ |
1417 // | caller stack param n | | 1417 // | caller stack param n | |
1418 // +-------------------------+<-spreg | 1418 // +-------------------------+<-spreg |
1419 // reg = number of parameters | 1419 // reg = number of parameters |
1420 // reg = failure handler address | 1420 // reg = failure handler address |
1421 // reg = saved frame | 1421 // reg = saved frame |
1422 // reg = JSFunction context | 1422 // reg = JSFunction context |
1423 // | 1423 // |
| 1424 // Caller stack params contain the register parameters to the stub first, |
| 1425 // and then, if the descriptor specifies a constant number of stack |
| 1426 // parameters, the stack parameters as well. |
1424 | 1427 |
1425 TranslatedFrame* translated_frame = | 1428 TranslatedFrame* translated_frame = |
1426 &(translated_state_.frames()[frame_index]); | 1429 &(translated_state_.frames()[frame_index]); |
1427 TranslatedFrame::iterator value_iterator = translated_frame->begin(); | 1430 TranslatedFrame::iterator value_iterator = translated_frame->begin(); |
1428 int input_index = 0; | 1431 int input_index = 0; |
1429 | 1432 |
1430 CHECK(compiled_code_->is_hydrogen_stub()); | 1433 CHECK(compiled_code_->is_hydrogen_stub()); |
1431 int major_key = CodeStub::GetMajorKey(compiled_code_); | 1434 int major_key = CodeStub::GetMajorKey(compiled_code_); |
1432 CodeStubDescriptor descriptor(isolate_, compiled_code_->stub_key()); | 1435 CodeStubDescriptor descriptor(isolate_, compiled_code_->stub_key()); |
1433 | 1436 |
1434 // The output frame must have room for all pushed register parameters | 1437 // The output frame must have room for all pushed register parameters |
1435 // and the standard stack frame slots. Include space for an argument | 1438 // and the standard stack frame slots. Include space for an argument |
1436 // object to the callee and optionally the space to pass the argument | 1439 // object to the callee and optionally the space to pass the argument |
1437 // object to the stub failure handler. | 1440 // object to the stub failure handler. |
1438 int param_count = descriptor.GetRegisterParameterCount(); | 1441 int param_count = descriptor.GetRegisterParameterCount(); |
| 1442 int stack_param_count = descriptor.GetStackParameterCount(); |
1439 CHECK_EQ(translated_frame->height(), param_count); | 1443 CHECK_EQ(translated_frame->height(), param_count); |
1440 CHECK_GE(param_count, 0); | 1444 CHECK_GE(param_count, 0); |
1441 | 1445 |
1442 int height_in_bytes = kPointerSize * param_count + sizeof(Arguments) + | 1446 int height_in_bytes = kPointerSize * (param_count + stack_param_count) + |
1443 kPointerSize; | 1447 sizeof(Arguments) + kPointerSize; |
1444 int fixed_frame_size = StandardFrameConstants::kFixedFrameSize; | 1448 int fixed_frame_size = StandardFrameConstants::kFixedFrameSize; |
1445 int input_frame_size = input_->GetFrameSize(); | 1449 int input_frame_size = input_->GetFrameSize(); |
1446 int output_frame_size = height_in_bytes + fixed_frame_size; | 1450 int output_frame_size = height_in_bytes + fixed_frame_size; |
1447 if (trace_scope_ != NULL) { | 1451 if (trace_scope_ != NULL) { |
1448 PrintF(trace_scope_->file(), | 1452 PrintF(trace_scope_->file(), |
1449 " translating %s => StubFailureTrampolineStub, height=%d\n", | 1453 " translating %s => StubFailureTrampolineStub, height=%d\n", |
1450 CodeStub::MajorName(static_cast<CodeStub::Major>(major_key), false), | 1454 CodeStub::MajorName(static_cast<CodeStub::Major>(major_key), false), |
1451 height_in_bytes); | 1455 height_in_bytes); |
1452 } | 1456 } |
1453 | 1457 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1506 DebugPrintOutputSlot(value, frame_index, output_frame_offset, "context\n"); | 1510 DebugPrintOutputSlot(value, frame_index, output_frame_offset, "context\n"); |
1507 | 1511 |
1508 // A marker value is used in place of the function. | 1512 // A marker value is used in place of the function. |
1509 output_frame_offset -= kPointerSize; | 1513 output_frame_offset -= kPointerSize; |
1510 value = reinterpret_cast<intptr_t>( | 1514 value = reinterpret_cast<intptr_t>( |
1511 Smi::FromInt(StackFrame::STUB_FAILURE_TRAMPOLINE)); | 1515 Smi::FromInt(StackFrame::STUB_FAILURE_TRAMPOLINE)); |
1512 output_frame->SetFrameSlot(output_frame_offset, value); | 1516 output_frame->SetFrameSlot(output_frame_offset, value); |
1513 DebugPrintOutputSlot(value, frame_index, output_frame_offset, | 1517 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
1514 "function (stub failure sentinel)\n"); | 1518 "function (stub failure sentinel)\n"); |
1515 | 1519 |
1516 intptr_t caller_arg_count = 0; | 1520 intptr_t caller_arg_count = stack_param_count; |
1517 bool arg_count_known = !descriptor.stack_parameter_count().is_valid(); | 1521 bool arg_count_known = !descriptor.stack_parameter_count().is_valid(); |
1518 | 1522 |
1519 // Build the Arguments object for the caller's parameters and a pointer to it. | 1523 // Build the Arguments object for the caller's parameters and a pointer to it. |
1520 output_frame_offset -= kPointerSize; | 1524 output_frame_offset -= kPointerSize; |
1521 int args_arguments_offset = output_frame_offset; | 1525 int args_arguments_offset = output_frame_offset; |
1522 intptr_t the_hole = reinterpret_cast<intptr_t>( | 1526 intptr_t the_hole = reinterpret_cast<intptr_t>( |
1523 isolate_->heap()->the_hole_value()); | 1527 isolate_->heap()->the_hole_value()); |
1524 if (arg_count_known) { | 1528 if (arg_count_known) { |
1525 value = frame_ptr + StandardFrameConstants::kCallerSPOffset + | 1529 value = frame_ptr + StandardFrameConstants::kCallerSPOffset + |
1526 (caller_arg_count - 1) * kPointerSize; | 1530 (caller_arg_count - 1) * kPointerSize; |
(...skipping 27 matching lines...) Expand all Loading... |
1554 WriteTranslatedValueToOutput(&value_iterator, &input_index, 0, | 1558 WriteTranslatedValueToOutput(&value_iterator, &input_index, 0, |
1555 output_frame_offset); | 1559 output_frame_offset); |
1556 | 1560 |
1557 if (!arg_count_known && | 1561 if (!arg_count_known && |
1558 descriptor.GetRegisterParameter(i) | 1562 descriptor.GetRegisterParameter(i) |
1559 .is(descriptor.stack_parameter_count())) { | 1563 .is(descriptor.stack_parameter_count())) { |
1560 arguments_length_offset = output_frame_offset; | 1564 arguments_length_offset = output_frame_offset; |
1561 } | 1565 } |
1562 } | 1566 } |
1563 | 1567 |
| 1568 // Copy constant stack parameters to the failure frame. If the number of stack |
| 1569 // parameters is not known in the descriptor, the arguments object is the way |
| 1570 // to access them. |
| 1571 for (int i = 0; i < stack_param_count; i++) { |
| 1572 output_frame_offset -= kPointerSize; |
| 1573 Object** stack_parameter = reinterpret_cast<Object**>( |
| 1574 frame_ptr + StandardFrameConstants::kCallerSPOffset + |
| 1575 (stack_param_count - i - 1) * kPointerSize); |
| 1576 value = reinterpret_cast<intptr_t>(*stack_parameter); |
| 1577 output_frame->SetFrameSlot(output_frame_offset, value); |
| 1578 DebugPrintOutputSlot(value, frame_index, output_frame_offset, |
| 1579 "stack parameter\n"); |
| 1580 } |
| 1581 |
1564 CHECK_EQ(0u, output_frame_offset); | 1582 CHECK_EQ(0u, output_frame_offset); |
1565 | 1583 |
1566 if (!arg_count_known) { | 1584 if (!arg_count_known) { |
1567 CHECK_GE(arguments_length_offset, 0); | 1585 CHECK_GE(arguments_length_offset, 0); |
1568 // We know it's a smi because 1) the code stub guarantees the stack | 1586 // We know it's a smi because 1) the code stub guarantees the stack |
1569 // parameter count is in smi range, and 2) the DoTranslateCommand in the | 1587 // parameter count is in smi range, and 2) the DoTranslateCommand in the |
1570 // parameter loop above translated that to a tagged value. | 1588 // parameter loop above translated that to a tagged value. |
1571 Smi* smi_caller_arg_count = reinterpret_cast<Smi*>( | 1589 Smi* smi_caller_arg_count = reinterpret_cast<Smi*>( |
1572 output_frame->GetFrameSlot(arguments_length_offset)); | 1590 output_frame->GetFrameSlot(arguments_length_offset)); |
1573 caller_arg_count = smi_caller_arg_count->value(); | 1591 caller_arg_count = smi_caller_arg_count->value(); |
1574 output_frame->SetFrameSlot(length_frame_offset, caller_arg_count); | 1592 output_frame->SetFrameSlot(length_frame_offset, caller_arg_count); |
1575 DebugPrintOutputSlot(caller_arg_count, frame_index, length_frame_offset, | 1593 DebugPrintOutputSlot(caller_arg_count, frame_index, length_frame_offset, |
1576 "args.length\n"); | 1594 "args.length\n"); |
1577 value = frame_ptr + StandardFrameConstants::kCallerSPOffset + | 1595 value = frame_ptr + StandardFrameConstants::kCallerSPOffset + |
1578 (caller_arg_count - 1) * kPointerSize; | 1596 (caller_arg_count - 1) * kPointerSize; |
1579 output_frame->SetFrameSlot(args_arguments_offset, value); | 1597 output_frame->SetFrameSlot(args_arguments_offset, value); |
1580 DebugPrintOutputSlot(value, frame_index, args_arguments_offset, | 1598 DebugPrintOutputSlot(value, frame_index, args_arguments_offset, |
1581 "args.arguments"); | 1599 "args.arguments"); |
1582 } | 1600 } |
1583 | 1601 |
1584 // Copy the double registers from the input into the output frame. | 1602 // Copy the double registers from the input into the output frame. |
1585 CopyDoubleRegisters(output_frame); | 1603 CopyDoubleRegisters(output_frame); |
1586 | 1604 |
1587 // Fill registers containing handler and number of parameters. | 1605 // Fill registers containing handler and number of parameters. |
1588 SetPlatformCompiledStubRegisters(output_frame, &descriptor); | 1606 SetPlatformCompiledStubRegisters(output_frame, &descriptor); |
1589 | 1607 |
1590 // Compute this frame's PC, state, and continuation. | 1608 // Compute this frame's PC, state, and continuation. |
1591 Code* trampoline = NULL; | 1609 Code* trampoline = NULL; |
1592 StubFunctionMode function_mode = descriptor.function_mode(); | 1610 StubFunctionMode function_mode = descriptor.function_mode(); |
1593 StubFailureTrampolineStub(isolate_, | 1611 StubFailureTrampolineStub(isolate_, function_mode) |
1594 function_mode).FindCodeInCache(&trampoline); | 1612 .FindCodeInCache(&trampoline); |
1595 DCHECK(trampoline != NULL); | 1613 DCHECK(trampoline != NULL); |
1596 output_frame->SetPc(reinterpret_cast<intptr_t>( | 1614 output_frame->SetPc(reinterpret_cast<intptr_t>( |
1597 trampoline->instruction_start())); | 1615 trampoline->instruction_start())); |
1598 if (FLAG_enable_embedded_constant_pool) { | 1616 if (FLAG_enable_embedded_constant_pool) { |
1599 Register constant_pool_reg = | 1617 Register constant_pool_reg = |
1600 StubFailureTrampolineFrame::constant_pool_pointer_register(); | 1618 StubFailureTrampolineFrame::constant_pool_pointer_register(); |
1601 intptr_t constant_pool_value = | 1619 intptr_t constant_pool_value = |
1602 reinterpret_cast<intptr_t>(trampoline->constant_pool()); | 1620 reinterpret_cast<intptr_t>(trampoline->constant_pool()); |
1603 output_frame->SetConstantPool(constant_pool_value); | 1621 output_frame->SetConstantPool(constant_pool_value); |
1604 output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value); | 1622 output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value); |
(...skipping 1783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3388 DCHECK(value_info->IsMaterializedObject()); | 3406 DCHECK(value_info->IsMaterializedObject()); |
3389 | 3407 |
3390 value_info->value_ = | 3408 value_info->value_ = |
3391 Handle<Object>(previously_materialized_objects->get(i), isolate_); | 3409 Handle<Object>(previously_materialized_objects->get(i), isolate_); |
3392 } | 3410 } |
3393 } | 3411 } |
3394 } | 3412 } |
3395 | 3413 |
3396 } // namespace internal | 3414 } // namespace internal |
3397 } // namespace v8 | 3415 } // namespace v8 |
OLD | NEW |