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

Side by Side Diff: runtime/vm/flow_graph_compiler_x64.cc

Issue 22825023: Uses an object pool on x64 (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 4 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 "vm/ast_printer.h" 10 #include "vm/ast_printer.h"
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 intptr_t slot_ix = 0; 59 intptr_t slot_ix = 0;
60 Environment* current = deopt_env_; 60 Environment* current = deopt_env_;
61 61
62 // Emit all kMaterializeObject instructions describing objects to be 62 // Emit all kMaterializeObject instructions describing objects to be
63 // materialized on the deoptimization as a prefix to the deoptimization info. 63 // materialized on the deoptimization as a prefix to the deoptimization info.
64 EmitMaterializations(deopt_env_, builder); 64 EmitMaterializations(deopt_env_, builder);
65 65
66 // The real frame starts here. 66 // The real frame starts here.
67 builder->MarkFrameStart(); 67 builder->MarkFrameStart();
68 68
69 // Callee's PC marker is not used anymore. Pass Function::null() to set to 0. 69 // Current PP, FP, and PC.
70 builder->AddPp(current->function(), slot_ix++);
70 builder->AddPcMarker(Function::Handle(), slot_ix++); 71 builder->AddPcMarker(Function::Handle(), slot_ix++);
71
72 // Current FP and PC.
73 builder->AddCallerFp(slot_ix++); 72 builder->AddCallerFp(slot_ix++);
74 builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++); 73 builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++);
75 74
76 // Emit all values that are needed for materialization as a part of the 75 // Emit all values that are needed for materialization as a part of the
77 // expression stack for the bottom-most frame. This guarantees that GC 76 // expression stack for the bottom-most frame. This guarantees that GC
78 // will be able to find them during materialization. 77 // will be able to find them during materialization.
79 slot_ix = builder->EmitMaterializationArguments(slot_ix); 78 slot_ix = builder->EmitMaterializationArguments(slot_ix);
80 79
81 // For the innermost environment, set outgoing arguments and the locals. 80 // For the innermost environment, set outgoing arguments and the locals.
82 for (intptr_t i = current->Length() - 1; 81 for (intptr_t i = current->Length() - 1;
83 i >= current->fixed_parameter_count(); 82 i >= current->fixed_parameter_count();
84 i--) { 83 i--) {
85 builder->AddCopy(current->ValueAt(i), current->LocationAt(i), slot_ix++); 84 builder->AddCopy(current->ValueAt(i), current->LocationAt(i), slot_ix++);
86 } 85 }
87 86
88 // Current PC marker and caller FP.
89 builder->AddPcMarker(current->function(), slot_ix++);
90 builder->AddCallerFp(slot_ix++);
91
92 Environment* previous = current; 87 Environment* previous = current;
93 current = current->outer(); 88 current = current->outer();
94 while (current != NULL) { 89 while (current != NULL) {
90 // PP, FP, and PC.
91 builder->AddPp(current->function(), slot_ix++);
92 builder->AddPcMarker(previous->function(), slot_ix++);
93 builder->AddCallerFp(slot_ix++);
94
95 // For any outer environment the deopt id is that of the call instruction 95 // For any outer environment the deopt id is that of the call instruction
96 // which is recorded in the outer environment. 96 // which is recorded in the outer environment.
97 builder->AddReturnAddress(current->function(), 97 builder->AddReturnAddress(current->function(),
98 Isolate::ToDeoptAfter(current->deopt_id()), 98 Isolate::ToDeoptAfter(current->deopt_id()),
99 slot_ix++); 99 slot_ix++);
100 100
101 // The values of outgoing arguments can be changed from the inlined call so 101 // The values of outgoing arguments can be changed from the inlined call so
102 // we must read them from the previous environment. 102 // we must read them from the previous environment.
103 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) { 103 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) {
104 builder->AddCopy(previous->ValueAt(i), 104 builder->AddCopy(previous->ValueAt(i),
105 previous->LocationAt(i), 105 previous->LocationAt(i),
106 slot_ix++); 106 slot_ix++);
107 } 107 }
108 108
109 // Set the locals, note that outgoing arguments are not in the environment. 109 // Set the locals, note that outgoing arguments are not in the environment.
110 for (intptr_t i = current->Length() - 1; 110 for (intptr_t i = current->Length() - 1;
111 i >= current->fixed_parameter_count(); 111 i >= current->fixed_parameter_count();
112 i--) { 112 i--) {
113 builder->AddCopy(current->ValueAt(i), 113 builder->AddCopy(current->ValueAt(i),
114 current->LocationAt(i), 114 current->LocationAt(i),
115 slot_ix++); 115 slot_ix++);
116 } 116 }
117 117
118 // PC marker and caller FP.
119 builder->AddPcMarker(current->function(), slot_ix++);
120 builder->AddCallerFp(slot_ix++);
121
122 // Iterate on the outer environment. 118 // Iterate on the outer environment.
123 previous = current; 119 previous = current;
124 current = current->outer(); 120 current = current->outer();
125 } 121 }
126 // The previous pointer is now the outermost environment. 122 // The previous pointer is now the outermost environment.
127 ASSERT(previous != NULL); 123 ASSERT(previous != NULL);
128 124
129 // For the outermost environment, set caller PC. 125 // For the outermost environment, set caller PC, caller PP, and caller FP.
126 builder->AddCallerPp(slot_ix++);
127 // PC marker.
128 builder->AddPcMarker(previous->function(), slot_ix++);
129 builder->AddCallerFp(slot_ix++);
130 builder->AddCallerPc(slot_ix++); 130 builder->AddCallerPc(slot_ix++);
131 131
132 // For the outermost environment, set the incoming arguments. 132 // For the outermost environment, set the incoming arguments.
133 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) { 133 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) {
134 builder->AddCopy(previous->ValueAt(i), previous->LocationAt(i), slot_ix++); 134 builder->AddCopy(previous->ValueAt(i), previous->LocationAt(i), slot_ix++);
135 } 135 }
136 136
137 const DeoptInfo& deopt_info = DeoptInfo::Handle(builder->CreateDeoptInfo()); 137 const DeoptInfo& deopt_info = DeoptInfo::Handle(builder->CreateDeoptInfo());
138 return deopt_info.raw(); 138 return deopt_info.raw();
139 } 139 }
140 140
141
142 void CompilerDeoptInfoWithStub::GenerateCode(FlowGraphCompiler* compiler, 141 void CompilerDeoptInfoWithStub::GenerateCode(FlowGraphCompiler* compiler,
143 intptr_t stub_ix) { 142 intptr_t stub_ix) {
144 // Calls do not need stubs, they share a deoptimization trampoline. 143 // Calls do not need stubs, they share a deoptimization trampoline.
145 ASSERT(reason() != kDeoptAtCall); 144 ASSERT(reason() != kDeoptAtCall);
146 Assembler* assem = compiler->assembler(); 145 Assembler* assem = compiler->assembler();
147 #define __ assem-> 146 #define __ assem->
148 __ Comment("Deopt stub for id %" Pd "", deopt_id()); 147 __ Comment("Deopt stub for id %" Pd "", deopt_id());
149 __ Bind(entry_label()); 148 __ Bind(entry_label());
150 if (FLAG_trap_on_deoptimization) __ int3(); 149 if (FLAG_trap_on_deoptimization) __ int3();
151 150
(...skipping 857 matching lines...) Expand 10 before | Expand all | Expand 10 after
1009 } 1008 }
1010 1009
1011 __ Bind(&wrong_num_arguments); 1010 __ Bind(&wrong_num_arguments);
1012 if (function.IsClosureFunction()) { 1011 if (function.IsClosureFunction()) {
1013 // Invoke noSuchMethod function passing "call" as the original name. 1012 // Invoke noSuchMethod function passing "call" as the original name.
1014 const int kNumArgsChecked = 1; 1013 const int kNumArgsChecked = 1;
1015 const ICData& ic_data = ICData::ZoneHandle( 1014 const ICData& ic_data = ICData::ZoneHandle(
1016 ICData::New(function, Symbols::Call(), Object::empty_array(), 1015 ICData::New(function, Symbols::Call(), Object::empty_array(),
1017 Isolate::kNoDeoptId, kNumArgsChecked)); 1016 Isolate::kNoDeoptId, kNumArgsChecked));
1018 __ LoadObject(RBX, ic_data); 1017 __ LoadObject(RBX, ic_data);
1019 __ LeaveFrame(); // The arguments are still on the stack. 1018 __ LeaveFrame(true); // The arguments are still on the stack.
1020 __ jmp(&StubCode::CallNoSuchMethodFunctionLabel()); 1019 __ jmp(&StubCode::CallNoSuchMethodFunctionLabel());
1021 // The noSuchMethod call may return to the caller, but not here. 1020 // The noSuchMethod call may return to the caller, but not here.
1022 __ int3(); 1021 __ int3();
1023 } else if (check_correct_named_args) { 1022 } else if (check_correct_named_args) {
1024 __ Stop("Wrong arguments"); 1023 __ Stop("Wrong arguments");
1025 } 1024 }
1026 1025
1027 __ Bind(&all_arguments_processed); 1026 __ Bind(&all_arguments_processed);
1028 // Nullify originally passed arguments only after they have been copied and 1027 // Nullify originally passed arguments only after they have been copied and
1029 // checked, otherwise noSuchMethod would not see their original values. 1028 // checked, otherwise noSuchMethod would not see their original values.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1070 __ ret(); 1069 __ ret();
1071 } 1070 }
1072 1071
1073 1072
1074 void FlowGraphCompiler::EmitFrameEntry() { 1073 void FlowGraphCompiler::EmitFrameEntry() {
1075 const Function& function = parsed_function().function(); 1074 const Function& function = parsed_function().function();
1076 if (CanOptimizeFunction() && 1075 if (CanOptimizeFunction() &&
1077 function.is_optimizable() && 1076 function.is_optimizable() &&
1078 (!is_optimizing() || may_reoptimize())) { 1077 (!is_optimizing() || may_reoptimize())) {
1079 const Register function_reg = RDI; 1078 const Register function_reg = RDI;
1079
1080
1081 // Temporarily load pool pointer.
1082 __ pushq(PP); // Preserve PP of caller.
1083 __ LoadPoolPointer();
1080 __ LoadObject(function_reg, function); 1084 __ LoadObject(function_reg, function);
1085 __ popq(PP); // Restore PP of caller.
1086
1081 // Patch point is after the eventually inlined function object. 1087 // Patch point is after the eventually inlined function object.
1082 AddCurrentDescriptor(PcDescriptors::kEntryPatch, 1088 AddCurrentDescriptor(PcDescriptors::kEntryPatch,
1083 Isolate::kNoDeoptId, 1089 Isolate::kNoDeoptId,
1084 0); // No token position. 1090 0); // No token position.
1085 if (is_optimizing()) { 1091 if (is_optimizing()) {
1086 // Reoptimization of an optimized function is triggered by counting in 1092 // Reoptimization of an optimized function is triggered by counting in
1087 // IC stubs, but not at the entry of the function. 1093 // IC stubs, but not at the entry of the function.
1088 __ cmpq(FieldAddress(function_reg, Function::usage_counter_offset()), 1094 __ cmpq(FieldAddress(function_reg, Function::usage_counter_offset()),
1089 Immediate(FLAG_reoptimization_counter_threshold)); 1095 Immediate(FLAG_reoptimization_counter_threshold));
1090 } else { 1096 } else {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1163 // For closure functions, use "call" as the original name. 1169 // For closure functions, use "call" as the original name.
1164 const String& name = 1170 const String& name =
1165 String::Handle(function.IsClosureFunction() 1171 String::Handle(function.IsClosureFunction()
1166 ? Symbols::Call().raw() 1172 ? Symbols::Call().raw()
1167 : function.name()); 1173 : function.name());
1168 const int kNumArgsChecked = 1; 1174 const int kNumArgsChecked = 1;
1169 const ICData& ic_data = ICData::ZoneHandle( 1175 const ICData& ic_data = ICData::ZoneHandle(
1170 ICData::New(function, name, Object::empty_array(), 1176 ICData::New(function, name, Object::empty_array(),
1171 Isolate::kNoDeoptId, kNumArgsChecked)); 1177 Isolate::kNoDeoptId, kNumArgsChecked));
1172 __ LoadObject(RBX, ic_data); 1178 __ LoadObject(RBX, ic_data);
1173 __ LeaveFrame(); // The arguments are still on the stack. 1179 __ LeaveFrame(true); // The arguments are still on the stack.
1174 __ jmp(&StubCode::CallNoSuchMethodFunctionLabel()); 1180 __ jmp(&StubCode::CallNoSuchMethodFunctionLabel());
1175 // The noSuchMethod call may return to the caller, but not here. 1181 // The noSuchMethod call may return to the caller, but not here.
1176 __ int3(); 1182 __ int3();
1177 } else { 1183 } else {
1178 __ Stop("Wrong number of arguments"); 1184 __ Stop("Wrong number of arguments");
1179 } 1185 }
1180 __ Bind(&correct_num_arguments); 1186 __ Bind(&correct_num_arguments);
1181 } 1187 }
1182 } else if (!flow_graph().IsCompiledForOsr()) { 1188 } else if (!flow_graph().IsCompiledForOsr()) {
1183 CopyParameters(); 1189 CopyParameters();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1222 Isolate::kNoDeoptId, 1228 Isolate::kNoDeoptId,
1223 0); // No token position. 1229 0); // No token position.
1224 __ jmp(&StubCode::DeoptimizeLazyLabel()); 1230 __ jmp(&StubCode::DeoptimizeLazyLabel());
1225 } 1231 }
1226 1232
1227 1233
1228 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, 1234 void FlowGraphCompiler::GenerateCall(intptr_t token_pos,
1229 const ExternalLabel* label, 1235 const ExternalLabel* label,
1230 PcDescriptors::Kind kind, 1236 PcDescriptors::Kind kind,
1231 LocationSummary* locs) { 1237 LocationSummary* locs) {
1232 __ call(label); 1238 __ CallPatchable(label);
1233 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos); 1239 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos);
1234 RecordSafepoint(locs); 1240 RecordSafepoint(locs);
1235 } 1241 }
1236 1242
1237 1243
1238 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id, 1244 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
1239 intptr_t token_pos, 1245 intptr_t token_pos,
1240 const ExternalLabel* label, 1246 const ExternalLabel* label,
1241 PcDescriptors::Kind kind, 1247 PcDescriptors::Kind kind,
1242 LocationSummary* locs) { 1248 LocationSummary* locs) {
1243 __ call(label); 1249 __ CallPatchable(label);
1244 AddCurrentDescriptor(kind, deopt_id, token_pos); 1250 AddCurrentDescriptor(kind, deopt_id, token_pos);
1245 RecordSafepoint(locs); 1251 RecordSafepoint(locs);
1246 // Marks either the continuation point in unoptimized code or the 1252 // Marks either the continuation point in unoptimized code or the
1247 // deoptimization point in optimized code, after call. 1253 // deoptimization point in optimized code, after call.
1248 const intptr_t deopt_id_after = Isolate::ToDeoptAfter(deopt_id); 1254 const intptr_t deopt_id_after = Isolate::ToDeoptAfter(deopt_id);
1249 if (is_optimizing()) { 1255 if (is_optimizing()) {
1250 AddDeoptIndexAtCall(deopt_id_after, token_pos); 1256 AddDeoptIndexAtCall(deopt_id_after, token_pos);
1251 } else { 1257 } else {
1252 // Add deoptimization continuation point after the call and before the 1258 // Add deoptimization continuation point after the call and before the
1253 // arguments are removed. 1259 // arguments are removed.
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
1606 BranchInstr* branch) { 1612 BranchInstr* branch) {
1607 ASSERT(branch != NULL); 1613 ASSERT(branch != NULL);
1608 assembler()->comisd(left, right); 1614 assembler()->comisd(left, right);
1609 BlockEntryInstr* nan_result = (true_condition == NOT_EQUAL) ? 1615 BlockEntryInstr* nan_result = (true_condition == NOT_EQUAL) ?
1610 branch->true_successor() : branch->false_successor(); 1616 branch->true_successor() : branch->false_successor();
1611 assembler()->j(PARITY_EVEN, GetJumpLabel(nan_result)); 1617 assembler()->j(PARITY_EVEN, GetJumpLabel(nan_result));
1612 branch->EmitBranchOnCondition(this, true_condition); 1618 branch->EmitBranchOnCondition(this, true_condition);
1613 } 1619 }
1614 1620
1615 1621
1616
1617 void FlowGraphCompiler::EmitDoubleCompareBool(Condition true_condition, 1622 void FlowGraphCompiler::EmitDoubleCompareBool(Condition true_condition,
1618 FpuRegister left, 1623 FpuRegister left,
1619 FpuRegister right, 1624 FpuRegister right,
1620 Register result) { 1625 Register result) {
1621 assembler()->comisd(left, right); 1626 assembler()->comisd(left, right);
1622 Label is_false, is_true, done; 1627 Label is_false, is_true, done;
1623 assembler()->j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN false; 1628 assembler()->j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN false;
1624 assembler()->j(true_condition, &is_true, Assembler::kNearJump); 1629 assembler()->j(true_condition, &is_true, Assembler::kNearJump);
1625 assembler()->Bind(&is_false); 1630 assembler()->Bind(&is_false);
1626 assembler()->LoadObject(result, Bool::False()); 1631 assembler()->LoadObject(result, Bool::False());
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
1889 __ movups(reg, Address(RSP, 0)); 1894 __ movups(reg, Address(RSP, 0));
1890 __ addq(RSP, Immediate(kFpuRegisterSize)); 1895 __ addq(RSP, Immediate(kFpuRegisterSize));
1891 } 1896 }
1892 1897
1893 1898
1894 #undef __ 1899 #undef __
1895 1900
1896 } // namespace dart 1901 } // namespace dart
1897 1902
1898 #endif // defined TARGET_ARCH_X64 1903 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698