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

Side by Side Diff: vm/flow_graph_compiler_x64.cc

Issue 10375059: Use a reserved stack local variable to store the Code object so that it can be looked up easily whe… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/flow_graph_compiler.h" 8 #include "vm/flow_graph_compiler.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 } 657 }
658 658
659 659
660 void FlowGraphCompiler::VisitNativeCall(NativeCallComp* comp) { 660 void FlowGraphCompiler::VisitNativeCall(NativeCallComp* comp) {
661 // Push the result place holder initialized to NULL. 661 // Push the result place holder initialized to NULL.
662 __ PushObject(Object::ZoneHandle()); 662 __ PushObject(Object::ZoneHandle());
663 // Pass a pointer to the first argument in RAX. 663 // Pass a pointer to the first argument in RAX.
664 if (!comp->has_optional_parameters()) { 664 if (!comp->has_optional_parameters()) {
665 __ leaq(RAX, Address(RBP, (1 + comp->argument_count()) * kWordSize)); 665 __ leaq(RAX, Address(RBP, (1 + comp->argument_count()) * kWordSize));
666 } else { 666 } else {
667 __ leaq(RAX, Address(RBP, -1 * kWordSize)); 667 __ leaq(RAX,
668 Address(RBP, ParsedFunction::kFirstStackSlotIndex * kWordSize));
668 } 669 }
669 __ movq(RBX, Immediate(reinterpret_cast<uword>(comp->native_c_function()))); 670 __ movq(RBX, Immediate(reinterpret_cast<uword>(comp->native_c_function())));
670 __ movq(R10, Immediate(comp->argument_count())); 671 __ movq(R10, Immediate(comp->argument_count()));
671 GenerateCall(comp->token_index(), 672 GenerateCall(comp->token_index(),
672 comp->try_index(), 673 comp->try_index(),
673 &StubCode::CallNativeCFunctionLabel(), 674 &StubCode::CallNativeCFunctionLabel(),
674 PcDescriptors::kOther); 675 PcDescriptors::kOther);
675 __ popq(RAX); 676 __ popq(RAX);
676 } 677 }
677 678
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
1130 } 1131 }
1131 1132
1132 1133
1133 // Restore stack and initialize the two exception variables: 1134 // Restore stack and initialize the two exception variables:
1134 // exception and stack trace variables. 1135 // exception and stack trace variables.
1135 void FlowGraphCompiler::VisitCatchEntry(CatchEntryComp* comp) { 1136 void FlowGraphCompiler::VisitCatchEntry(CatchEntryComp* comp) {
1136 // Restore RSP from RBP as we are coming from a throw and the code for 1137 // Restore RSP from RBP as we are coming from a throw and the code for
1137 // popping arguments has not been run. 1138 // popping arguments has not been run.
1138 const intptr_t locals_space_size = StackSize() * kWordSize; 1139 const intptr_t locals_space_size = StackSize() * kWordSize;
1139 ASSERT(locals_space_size >= 0); 1140 ASSERT(locals_space_size >= 0);
1140 if (locals_space_size == 0) { 1141 intptr_t offset_size = -locals_space_size + kLocalsOffsetFromFP;
1141 __ movq(RSP, RBP); 1142 __ leaq(RSP, Address(RBP, offset_size));
1142 } else {
1143 __ leaq(RSP, Address(RBP, -locals_space_size));
1144 }
1145 1143
1146 ASSERT(!comp->exception_var().is_captured()); 1144 ASSERT(!comp->exception_var().is_captured());
1147 ASSERT(!comp->stacktrace_var().is_captured()); 1145 ASSERT(!comp->stacktrace_var().is_captured());
1148 __ movq(Address(RBP, comp->exception_var().index() * kWordSize), 1146 __ movq(Address(RBP, comp->exception_var().index() * kWordSize),
1149 kExceptionObjectReg); 1147 kExceptionObjectReg);
1150 __ movq(Address(RBP, comp->stacktrace_var().index() * kWordSize), 1148 __ movq(Address(RBP, comp->stacktrace_var().index() * kWordSize),
1151 kStackTraceObjectReg); 1149 kStackTraceObjectReg);
1152 } 1150 }
1153 1151
1154 1152
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
1325 } 1323 }
1326 } 1324 }
1327 1325
1328 1326
1329 // Coped from CodeGenerator::CopyParameters (CodeGenerator will be deprecated). 1327 // Coped from CodeGenerator::CopyParameters (CodeGenerator will be deprecated).
1330 void FlowGraphCompiler::CopyParameters() { 1328 void FlowGraphCompiler::CopyParameters() {
1331 const Function& function = parsed_function_.function(); 1329 const Function& function = parsed_function_.function();
1332 LocalScope* scope = parsed_function_.node_sequence()->scope(); 1330 LocalScope* scope = parsed_function_.node_sequence()->scope();
1333 const int num_fixed_params = function.num_fixed_parameters(); 1331 const int num_fixed_params = function.num_fixed_parameters();
1334 const int num_opt_params = function.num_optional_parameters(); 1332 const int num_opt_params = function.num_optional_parameters();
1335 ASSERT(parsed_function_.first_parameter_index() == -1); 1333 ASSERT(parsed_function_.first_parameter_index() ==
1334 ParsedFunction::kFirstStackSlotIndex);
1336 // Copy positional arguments. 1335 // Copy positional arguments.
1337 // Check that no fewer than num_fixed_params positional arguments are passed 1336 // Check that no fewer than num_fixed_params positional arguments are passed
1338 // in and that no more than num_params arguments are passed in. 1337 // in and that no more than num_params arguments are passed in.
1339 // Passed argument i at fp[1 + argc - i] copied to fp[-1 - i]. 1338 // Passed argument i at fp[1 + argc - i]
1339 // copied to fp[ParsedFunction::kFirstStackSlotIndex - i].
1340 const int num_params = num_fixed_params + num_opt_params; 1340 const int num_params = num_fixed_params + num_opt_params;
1341 1341
1342 // Total number of args is the first Smi in args descriptor array (R10). 1342 // Total number of args is the first Smi in args descriptor array (R10).
1343 __ movq(RBX, FieldAddress(R10, Array::data_offset())); 1343 __ movq(RBX, FieldAddress(R10, Array::data_offset()));
1344 // Check that num_args <= num_params. 1344 // Check that num_args <= num_params.
1345 Label wrong_num_arguments; 1345 Label wrong_num_arguments;
1346 __ cmpq(RBX, Immediate(Smi::RawValue(num_params))); 1346 __ cmpq(RBX, Immediate(Smi::RawValue(num_params)));
1347 __ j(GREATER, &wrong_num_arguments); 1347 __ j(GREATER, &wrong_num_arguments);
1348 // Number of positional args is the second Smi in descriptor array (R10). 1348 // Number of positional args is the second Smi in descriptor array (R10).
1349 __ movq(RCX, FieldAddress(R10, Array::data_offset() + (1 * kWordSize))); 1349 __ movq(RCX, FieldAddress(R10, Array::data_offset() + (1 * kWordSize)));
1350 // Check that num_pos_args >= num_fixed_params. 1350 // Check that num_pos_args >= num_fixed_params.
1351 __ cmpq(RCX, Immediate(Smi::RawValue(num_fixed_params))); 1351 __ cmpq(RCX, Immediate(Smi::RawValue(num_fixed_params)));
1352 __ j(LESS, &wrong_num_arguments); 1352 __ j(LESS, &wrong_num_arguments);
1353 // Since RBX and RCX are Smi, use TIMES_4 instead of TIMES_8. 1353 // Since RBX and RCX are Smi, use TIMES_4 instead of TIMES_8.
1354 // Let RBX point to the last passed positional argument, i.e. to 1354 // Let RBX point to the last passed positional argument, i.e. to
1355 // fp[1 + num_args - (num_pos_args - 1)]. 1355 // fp[1 + num_args - (num_pos_args - 1)].
1356 __ subq(RBX, RCX); 1356 __ subq(RBX, RCX);
1357 __ leaq(RBX, Address(RBP, RBX, TIMES_4, 2 * kWordSize)); 1357 __ leaq(RBX, Address(RBP, RBX, TIMES_4, 2 * kWordSize));
1358 // Let RDI point to the last copied positional argument, i.e. to 1358 // Let RDI point to the last copied positional argument, i.e. to
1359 // fp[-1 - (num_pos_args - 1)]. 1359 // fp[ParsedFunction::kFirstStackSlotIndex - (num_pos_args - 1)].
1360 __ SmiUntag(RCX); 1360 __ SmiUntag(RCX);
1361 __ movq(RAX, RCX); 1361 __ movq(RAX, RCX);
1362 __ negq(RAX); 1362 __ negq(RAX);
1363 __ leaq(RDI, Address(RBP, RAX, TIMES_8, 0)); 1363 int index = ParsedFunction::kFirstStackSlotIndex + 1;
regis 2012/05/14 17:33:10 const
siva 2012/05/15 23:52:39 Done.
1364 // -num_pos_args is in RAX.
1365 // (ParsedFunction::kFirstStackSlotIndex + 1) is in index.
1366 __ leaq(RDI, Address(RBP, RAX, TIMES_8, (index * kWordSize)));
1364 Label loop, loop_condition; 1367 Label loop, loop_condition;
1365 __ jmp(&loop_condition, Assembler::kNearJump); 1368 __ jmp(&loop_condition, Assembler::kNearJump);
1366 // We do not use the final allocation index of the variable here, i.e. 1369 // We do not use the final allocation index of the variable here, i.e.
1367 // scope->VariableAt(i)->index(), because captured variables still need 1370 // scope->VariableAt(i)->index(), because captured variables still need
1368 // to be copied to the context that is not yet allocated. 1371 // to be copied to the context that is not yet allocated.
1369 const Address argument_addr(RBX, RCX, TIMES_8, 0); 1372 const Address argument_addr(RBX, RCX, TIMES_8, 0);
1370 const Address copy_addr(RDI, RCX, TIMES_8, 0); 1373 const Address copy_addr(RDI, RCX, TIMES_8, 0);
1371 __ Bind(&loop); 1374 __ Bind(&loop);
1372 __ movq(RAX, argument_addr); 1375 __ movq(RAX, argument_addr);
1373 __ movq(copy_addr, RAX); 1376 __ movq(copy_addr, RAX);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1425 Address argument_addr(RBX, RAX, TIMES_4, 0); // RAX is a negative Smi. 1428 Address argument_addr(RBX, RAX, TIMES_4, 0); // RAX is a negative Smi.
1426 __ movq(RAX, argument_addr); 1429 __ movq(RAX, argument_addr);
1427 __ jmp(&assign_optional_parameter, Assembler::kNearJump); 1430 __ jmp(&assign_optional_parameter, Assembler::kNearJump);
1428 __ Bind(&load_default_value); 1431 __ Bind(&load_default_value);
1429 // Load RAX with default argument at pos. 1432 // Load RAX with default argument at pos.
1430 const Object& value = Object::ZoneHandle( 1433 const Object& value = Object::ZoneHandle(
1431 parsed_function_.default_parameter_values().At( 1434 parsed_function_.default_parameter_values().At(
1432 param_pos - num_fixed_params)); 1435 param_pos - num_fixed_params));
1433 __ LoadObject(RAX, value); 1436 __ LoadObject(RAX, value);
1434 __ Bind(&assign_optional_parameter); 1437 __ Bind(&assign_optional_parameter);
1435 // Assign RAX to fp[-1 - param_pos]. 1438 // Assign RAX to fp[ParsedFunction::kFirstStackSlotIndex - param_pos].
1436 // We do not use the final allocation index of the variable here, i.e. 1439 // We do not use the final allocation index of the variable here, i.e.
1437 // scope->VariableAt(i)->index(), because captured variables still need 1440 // scope->VariableAt(i)->index(), because captured variables still need
1438 // to be copied to the context that is not yet allocated. 1441 // to be copied to the context that is not yet allocated.
1439 const Address param_addr(RBP, (-1 - param_pos) * kWordSize); 1442 const Address param_addr(
1443 RBP, (ParsedFunction::kFirstStackSlotIndex - param_pos) * kWordSize);
1440 __ movq(param_addr, RAX); 1444 __ movq(param_addr, RAX);
1441 __ Bind(&next_parameter); 1445 __ Bind(&next_parameter);
1442 } 1446 }
1443 delete[] opt_param; 1447 delete[] opt_param;
1444 delete[] opt_param_position; 1448 delete[] opt_param_position;
1445 // Check that RDI now points to the null terminator in the array descriptor. 1449 // Check that RDI now points to the null terminator in the array descriptor.
1446 const Immediate raw_null = 1450 const Immediate raw_null =
1447 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1451 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1448 Label all_arguments_processed; 1452 Label all_arguments_processed;
1449 __ cmpq(Address(RDI, 0), raw_null); 1453 __ cmpq(Address(RDI, 0), raw_null);
1450 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); 1454 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump);
1451 1455
1452 __ Bind(&wrong_num_arguments); 1456 __ Bind(&wrong_num_arguments);
1457 if (StackSize() != 0) {
1458 // We need to unwind the space we reserved for locals/copied parms etc.
regis 2012/05/14 17:33:10 ditto
siva 2012/05/15 23:52:39 Yes, I incorporated your comment into the other CL
1459 // as the NoSuchMethodFunction stub does not expect to see that area on
1460 // the stack.
1461 __ addq(RSP, Immediate(StackSize() * kWordSize));
1462 }
1453 if (function.IsClosureFunction()) { 1463 if (function.IsClosureFunction()) {
1454 GenerateCallRuntime(AstNode::kNoId, 1464 GenerateCallRuntime(AstNode::kNoId,
1455 0, 1465 0,
1456 CatchClauseNode::kInvalidTryIndex, 1466 CatchClauseNode::kInvalidTryIndex,
1457 kClosureArgumentMismatchRuntimeEntry); 1467 kClosureArgumentMismatchRuntimeEntry);
1458 } else { 1468 } else {
1459 // Invoke noSuchMethod function. 1469 // Invoke noSuchMethod function.
1460 const int kNumArgsChecked = 1; 1470 const int kNumArgsChecked = 1;
1461 ICData& ic_data = ICData::ZoneHandle(); 1471 ICData& ic_data = ICData::ZoneHandle();
1462 ic_data = ICData::New(parsed_function_.function(), 1472 ic_data = ICData::New(parsed_function_.function(),
1463 String::Handle(function.name()), 1473 String::Handle(function.name()),
1464 AstNode::kNoId, 1474 AstNode::kNoId,
1465 kNumArgsChecked); 1475 kNumArgsChecked);
1466 __ LoadObject(RBX, ic_data); 1476 __ LoadObject(RBX, ic_data);
1477 // RBP - 8 : PC marker, allows easy identification of RawInstruction obj.
1467 // RBP : points to previous frame pointer. 1478 // RBP : points to previous frame pointer.
1468 // RBP + 8 : points to return address. 1479 // RBP + 8 : points to return address.
1469 // RBP + 16 : address of last argument (arg n-1). 1480 // RBP + 16 : address of last argument (arg n-1).
1470 // RSP + 16 + 8*(n-1) : address of first argument (arg 0). 1481 // RSP + 16 + 8*(n-1) : address of first argument (arg 0).
1471 // RBX : ic-data. 1482 // RBX : ic-data.
1472 // R10 : arguments descriptor array. 1483 // R10 : arguments descriptor array.
1473 __ call(&StubCode::CallNoSuchMethodFunctionLabel()); 1484 __ call(&StubCode::CallNoSuchMethodFunctionLabel());
1474 } 1485 }
1475 1486
1476 if (FLAG_trace_functions) { 1487 if (FLAG_trace_functions) {
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1590 __ int3(); 1601 __ int3();
1591 __ jmp(&StubCode::FixCallersTargetLabel()); 1602 __ jmp(&StubCode::FixCallersTargetLabel());
1592 return; 1603 return;
1593 } 1604 }
1594 // Specialized version of entry code from CodeGenerator::GenerateEntryCode. 1605 // Specialized version of entry code from CodeGenerator::GenerateEntryCode.
1595 const Function& function = parsed_function_.function(); 1606 const Function& function = parsed_function_.function();
1596 1607
1597 const int parameter_count = function.num_fixed_parameters(); 1608 const int parameter_count = function.num_fixed_parameters();
1598 const int num_copied_params = parsed_function_.copied_parameter_count(); 1609 const int num_copied_params = parsed_function_.copied_parameter_count();
1599 const int local_count = parsed_function_.stack_local_count(); 1610 const int local_count = parsed_function_.stack_local_count();
1600 __ EnterFrame(StackSize() * kWordSize); 1611 AssemblerMacros::EnterDartFrame(assembler_, (StackSize() * kWordSize));
1601 1612
1602 // We check the number of passed arguments when we have to copy them due to 1613 // We check the number of passed arguments when we have to copy them due to
1603 // the presence of optional named parameters. 1614 // the presence of optional named parameters.
1604 // No such checking code is generated if only fixed parameters are declared, 1615 // No such checking code is generated if only fixed parameters are declared,
1605 // unless we are debug mode or unless we are compiling a closure. 1616 // unless we are debug mode or unless we are compiling a closure.
1606 if (num_copied_params == 0) { 1617 if (num_copied_params == 0) {
1607 #ifdef DEBUG 1618 #ifdef DEBUG
1608 const bool check_arguments = true; 1619 const bool check_arguments = true;
1609 #else 1620 #else
1610 const bool check_arguments = function.IsClosureFunction(); 1621 const bool check_arguments = function.IsClosureFunction();
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1733 ASSERT(exception_handlers_list_ != NULL); 1744 ASSERT(exception_handlers_list_ != NULL);
1734 const ExceptionHandlers& handlers = ExceptionHandlers::Handle( 1745 const ExceptionHandlers& handlers = ExceptionHandlers::Handle(
1735 exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint())); 1746 exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint()));
1736 code.set_exception_handlers(handlers); 1747 code.set_exception_handlers(handlers);
1737 } 1748 }
1738 1749
1739 1750
1740 } // namespace dart 1751 } // namespace dart
1741 1752
1742 #endif // defined TARGET_ARCH_X64 1753 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698