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

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

Issue 1270803003: VM: More abstract interface for generating stub calls. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 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
« no previous file with comments | « runtime/vm/flow_graph_compiler_arm64.cc ('k') | runtime/vm/flow_graph_compiler_mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
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 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 Assembler* assem = compiler->assembler(); 186 Assembler* assem = compiler->assembler();
187 #define __ assem-> 187 #define __ assem->
188 __ Comment("%s", Name()); 188 __ Comment("%s", Name());
189 __ Bind(entry_label()); 189 __ Bind(entry_label());
190 if (FLAG_trap_on_deoptimization) { 190 if (FLAG_trap_on_deoptimization) {
191 __ int3(); 191 __ int3();
192 } 192 }
193 193
194 ASSERT(deopt_env() != NULL); 194 ASSERT(deopt_env() != NULL);
195 195
196 __ call(&StubCode::DeoptimizeLabel()); 196 __ Call(*StubCode::Deoptimize_entry());
197 set_pc_offset(assem->CodeSize()); 197 set_pc_offset(assem->CodeSize());
198 __ int3(); 198 __ int3();
199 #undef __ 199 #undef __
200 } 200 }
201 201
202 202
203 #define __ assembler()-> 203 #define __ assembler()->
204 204
205 205
206 // Fall through if bool_register contains null. 206 // Fall through if bool_register contains null.
(...skipping 23 matching lines...) Expand all
230 const SubtypeTestCache& type_test_cache = 230 const SubtypeTestCache& type_test_cache =
231 SubtypeTestCache::ZoneHandle(zone(), SubtypeTestCache::New()); 231 SubtypeTestCache::ZoneHandle(zone(), SubtypeTestCache::New());
232 const Immediate& raw_null = 232 const Immediate& raw_null =
233 Immediate(reinterpret_cast<intptr_t>(Object::null())); 233 Immediate(reinterpret_cast<intptr_t>(Object::null()));
234 __ LoadObject(temp_reg, type_test_cache); 234 __ LoadObject(temp_reg, type_test_cache);
235 __ pushl(temp_reg); // Subtype test cache. 235 __ pushl(temp_reg); // Subtype test cache.
236 __ pushl(instance_reg); // Instance. 236 __ pushl(instance_reg); // Instance.
237 if (test_kind == kTestTypeOneArg) { 237 if (test_kind == kTestTypeOneArg) {
238 ASSERT(type_arguments_reg == kNoRegister); 238 ASSERT(type_arguments_reg == kNoRegister);
239 __ pushl(raw_null); 239 __ pushl(raw_null);
240 __ call(&StubCode::Subtype1TestCacheLabel()); 240 __ Call(*StubCode::Subtype1TestCache_entry());
241 } else if (test_kind == kTestTypeTwoArgs) { 241 } else if (test_kind == kTestTypeTwoArgs) {
242 ASSERT(type_arguments_reg == kNoRegister); 242 ASSERT(type_arguments_reg == kNoRegister);
243 __ pushl(raw_null); 243 __ pushl(raw_null);
244 __ call(&StubCode::Subtype2TestCacheLabel()); 244 __ Call(*StubCode::Subtype2TestCache_entry());
245 } else if (test_kind == kTestTypeThreeArgs) { 245 } else if (test_kind == kTestTypeThreeArgs) {
246 __ pushl(type_arguments_reg); 246 __ pushl(type_arguments_reg);
247 __ call(&StubCode::Subtype3TestCacheLabel()); 247 __ Call(*StubCode::Subtype3TestCache_entry());
248 } else { 248 } else {
249 UNREACHABLE(); 249 UNREACHABLE();
250 } 250 }
251 // Result is in ECX: null -> not found, otherwise Bool::True or Bool::False. 251 // Result is in ECX: null -> not found, otherwise Bool::True or Bool::False.
252 ASSERT(instance_reg != ECX); 252 ASSERT(instance_reg != ECX);
253 ASSERT(temp_reg != ECX); 253 ASSERT(temp_reg != ECX);
254 __ popl(instance_reg); // Discard. 254 __ popl(instance_reg); // Discard.
255 __ popl(instance_reg); // Restore receiver. 255 __ popl(instance_reg); // Restore receiver.
256 __ popl(temp_reg); // Discard. 256 __ popl(temp_reg); // Discard.
257 GenerateBoolToJump(ECX, is_instance_lbl, is_not_instance_lbl); 257 GenerateBoolToJump(ECX, is_instance_lbl, is_not_instance_lbl);
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after
936 __ SmiUntag(EBX); 936 __ SmiUntag(EBX);
937 // Check that ECX equals EBX, i.e. no named arguments passed. 937 // Check that ECX equals EBX, i.e. no named arguments passed.
938 __ cmpl(ECX, EBX); 938 __ cmpl(ECX, EBX);
939 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); 939 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump);
940 } 940 }
941 } 941 }
942 942
943 __ Bind(&wrong_num_arguments); 943 __ Bind(&wrong_num_arguments);
944 if (function.IsClosureFunction()) { 944 if (function.IsClosureFunction()) {
945 __ LeaveFrame(); // The arguments are still on the stack. 945 __ LeaveFrame(); // The arguments are still on the stack.
946 __ jmp(&StubCode::CallClosureNoSuchMethodLabel()); 946 __ Jmp(*StubCode::CallClosureNoSuchMethod_entry());
947 // The noSuchMethod call may return to the caller, but not here. 947 // The noSuchMethod call may return to the caller, but not here.
948 } else if (check_correct_named_args) { 948 } else if (check_correct_named_args) {
949 __ Stop("Wrong arguments"); 949 __ Stop("Wrong arguments");
950 } 950 }
951 951
952 __ Bind(&all_arguments_processed); 952 __ Bind(&all_arguments_processed);
953 // Nullify originally passed arguments only after they have been copied and 953 // Nullify originally passed arguments only after they have been copied and
954 // checked, otherwise noSuchMethod would not see their original values. 954 // checked, otherwise noSuchMethod would not see their original values.
955 // This step can be skipped in case we decide that formal parameters are 955 // This step can be skipped in case we decide that formal parameters are
956 // implicitly final, since garbage collecting the unmodified value is not 956 // implicitly final, since garbage collecting the unmodified value is not
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 entry_patch_pc_offset_ = assembler()->CodeSize(); 1012 entry_patch_pc_offset_ = assembler()->CodeSize();
1013 1013
1014 // Reoptimization of an optimized function is triggered by counting in 1014 // Reoptimization of an optimized function is triggered by counting in
1015 // IC stubs, but not at the entry of the function. 1015 // IC stubs, but not at the entry of the function.
1016 if (!is_optimizing()) { 1016 if (!is_optimizing()) {
1017 __ incl(FieldAddress(function_reg, Function::usage_counter_offset())); 1017 __ incl(FieldAddress(function_reg, Function::usage_counter_offset()));
1018 } 1018 }
1019 __ cmpl(FieldAddress(function_reg, Function::usage_counter_offset()), 1019 __ cmpl(FieldAddress(function_reg, Function::usage_counter_offset()),
1020 Immediate(GetOptimizationThreshold())); 1020 Immediate(GetOptimizationThreshold()));
1021 ASSERT(function_reg == EDI); 1021 ASSERT(function_reg == EDI);
1022 __ j(GREATER_EQUAL, &StubCode::OptimizeFunctionLabel()); 1022 __ J(GREATER_EQUAL, *StubCode::OptimizeFunction_entry());
1023 } else if (!flow_graph().IsCompiledForOsr()) { 1023 } else if (!flow_graph().IsCompiledForOsr()) {
1024 entry_patch_pc_offset_ = assembler()->CodeSize(); 1024 entry_patch_pc_offset_ = assembler()->CodeSize();
1025 } 1025 }
1026 __ Comment("Enter frame"); 1026 __ Comment("Enter frame");
1027 if (flow_graph().IsCompiledForOsr()) { 1027 if (flow_graph().IsCompiledForOsr()) {
1028 intptr_t extra_slots = StackSize() 1028 intptr_t extra_slots = StackSize()
1029 - flow_graph().num_stack_locals() 1029 - flow_graph().num_stack_locals()
1030 - flow_graph().num_copied_params(); 1030 - flow_graph().num_copied_params();
1031 ASSERT(extra_slots >= 0); 1031 ASSERT(extra_slots >= 0);
1032 __ EnterOsrFrame(extra_slots * kWordSize); 1032 __ EnterOsrFrame(extra_slots * kWordSize);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1070 __ cmpl(EAX, Immediate(Smi::RawValue(num_fixed_params))); 1070 __ cmpl(EAX, Immediate(Smi::RawValue(num_fixed_params)));
1071 __ j(NOT_EQUAL, &wrong_num_arguments, Assembler::kNearJump); 1071 __ j(NOT_EQUAL, &wrong_num_arguments, Assembler::kNearJump);
1072 __ cmpl(EAX, 1072 __ cmpl(EAX,
1073 FieldAddress(EDX, 1073 FieldAddress(EDX,
1074 ArgumentsDescriptor::positional_count_offset())); 1074 ArgumentsDescriptor::positional_count_offset()));
1075 __ j(EQUAL, &correct_num_arguments, Assembler::kNearJump); 1075 __ j(EQUAL, &correct_num_arguments, Assembler::kNearJump);
1076 1076
1077 __ Bind(&wrong_num_arguments); 1077 __ Bind(&wrong_num_arguments);
1078 if (function.IsClosureFunction()) { 1078 if (function.IsClosureFunction()) {
1079 __ LeaveFrame(); // The arguments are still on the stack. 1079 __ LeaveFrame(); // The arguments are still on the stack.
1080 __ jmp(&StubCode::CallClosureNoSuchMethodLabel()); 1080 __ Jmp(*StubCode::CallClosureNoSuchMethod_entry());
1081 // The noSuchMethod call may return to the caller, but not here. 1081 // The noSuchMethod call may return to the caller, but not here.
1082 } else { 1082 } else {
1083 __ Stop("Wrong number of arguments"); 1083 __ Stop("Wrong number of arguments");
1084 } 1084 }
1085 __ Bind(&correct_num_arguments); 1085 __ Bind(&correct_num_arguments);
1086 } 1086 }
1087 } else if (!flow_graph().IsCompiledForOsr()) { 1087 } else if (!flow_graph().IsCompiledForOsr()) {
1088 CopyParameters(); 1088 CopyParameters();
1089 } 1089 }
1090 1090
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1138 } 1138 }
1139 1139
1140 ASSERT(!block_order().is_empty()); 1140 ASSERT(!block_order().is_empty());
1141 VisitBlocks(); 1141 VisitBlocks();
1142 1142
1143 __ int3(); 1143 __ int3();
1144 GenerateDeferredCode(); 1144 GenerateDeferredCode();
1145 // Emit function patching code. This will be swapped with the first 5 bytes 1145 // Emit function patching code. This will be swapped with the first 5 bytes
1146 // at entry point. 1146 // at entry point.
1147 patch_code_pc_offset_ = assembler()->CodeSize(); 1147 patch_code_pc_offset_ = assembler()->CodeSize();
1148 __ jmp(&StubCode::FixCallersTargetLabel()); 1148 __ Jmp(*StubCode::FixCallersTarget_entry());
1149 1149
1150 if (is_optimizing()) { 1150 if (is_optimizing()) {
1151 lazy_deopt_pc_offset_ = assembler()->CodeSize(); 1151 lazy_deopt_pc_offset_ = assembler()->CodeSize();
1152 __ jmp(&StubCode::DeoptimizeLazyLabel()); 1152 __ Jmp(*StubCode::DeoptimizeLazy_entry());
1153 } 1153 }
1154 } 1154 }
1155 1155
1156 1156
1157 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, 1157 void FlowGraphCompiler::GenerateCall(intptr_t token_pos,
1158 const ExternalLabel* label, 1158 const StubEntry& stub_entry,
1159 RawPcDescriptors::Kind kind, 1159 RawPcDescriptors::Kind kind,
1160 LocationSummary* locs) { 1160 LocationSummary* locs) {
1161 __ call(label); 1161 __ Call(stub_entry);
1162 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos); 1162 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos);
1163 RecordSafepoint(locs); 1163 RecordSafepoint(locs);
1164 } 1164 }
1165 1165
1166 1166
1167 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id, 1167 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
1168 intptr_t token_pos, 1168 intptr_t token_pos,
1169 const ExternalLabel* label, 1169 const StubEntry& stub_entry,
1170 RawPcDescriptors::Kind kind, 1170 RawPcDescriptors::Kind kind,
1171 LocationSummary* locs) { 1171 LocationSummary* locs) {
1172 __ call(label); 1172 __ Call(stub_entry);
1173 AddCurrentDescriptor(kind, deopt_id, token_pos); 1173 AddCurrentDescriptor(kind, deopt_id, token_pos);
1174 RecordSafepoint(locs); 1174 RecordSafepoint(locs);
1175 // Marks either the continuation point in unoptimized code or the 1175 // Marks either the continuation point in unoptimized code or the
1176 // deoptimization point in optimized code, after call. 1176 // deoptimization point in optimized code, after call.
1177 const intptr_t deopt_id_after = Isolate::ToDeoptAfter(deopt_id); 1177 const intptr_t deopt_id_after = Isolate::ToDeoptAfter(deopt_id);
1178 if (is_optimizing()) { 1178 if (is_optimizing()) {
1179 AddDeoptIndexAtCall(deopt_id_after, token_pos); 1179 AddDeoptIndexAtCall(deopt_id_after, token_pos);
1180 } else { 1180 } else {
1181 // Add deoptimization continuation point after the call and before the 1181 // Add deoptimization continuation point after the call and before the
1182 // arguments are removed. 1182 // arguments are removed.
(...skipping 24 matching lines...) Expand all
1207 } 1207 }
1208 } 1208 }
1209 1209
1210 1210
1211 void FlowGraphCompiler::EmitUnoptimizedStaticCall( 1211 void FlowGraphCompiler::EmitUnoptimizedStaticCall(
1212 intptr_t argument_count, 1212 intptr_t argument_count,
1213 intptr_t deopt_id, 1213 intptr_t deopt_id,
1214 intptr_t token_pos, 1214 intptr_t token_pos,
1215 LocationSummary* locs, 1215 LocationSummary* locs,
1216 const ICData& ic_data) { 1216 const ICData& ic_data) {
1217 const uword label_address = 1217 const StubEntry& stub_entry =
1218 StubCode::UnoptimizedStaticCallEntryPoint(ic_data.NumArgsTested()); 1218 *StubCode::UnoptimizedStaticCallEntry(ic_data.NumArgsTested());
1219 ExternalLabel target_label(label_address);
1220 __ LoadObject(ECX, ic_data); 1219 __ LoadObject(ECX, ic_data);
1221 GenerateDartCall(deopt_id, 1220 GenerateDartCall(deopt_id,
1222 token_pos, 1221 token_pos,
1223 &target_label, 1222 stub_entry,
1224 RawPcDescriptors::kUnoptStaticCall, 1223 RawPcDescriptors::kUnoptStaticCall,
1225 locs); 1224 locs);
1226 __ Drop(argument_count); 1225 __ Drop(argument_count);
1227 } 1226 }
1228 1227
1229 1228
1230 void FlowGraphCompiler::EmitEdgeCounter() { 1229 void FlowGraphCompiler::EmitEdgeCounter() {
1231 // We do not check for overflow when incrementing the edge counter. The 1230 // We do not check for overflow when incrementing the edge counter. The
1232 // function should normally be optimized long before the counter can 1231 // function should normally be optimized long before the counter can
1233 // overflow; and though we do not reset the counters when we optimize or 1232 // overflow; and though we do not reset the counters when we optimize or
(...skipping 15 matching lines...) Expand all
1249 1248
1250 1249
1251 int32_t FlowGraphCompiler::EdgeCounterIncrementSizeInBytes() { 1250 int32_t FlowGraphCompiler::EdgeCounterIncrementSizeInBytes() {
1252 const int32_t size = Isolate::Current()->edge_counter_increment_size(); 1251 const int32_t size = Isolate::Current()->edge_counter_increment_size();
1253 ASSERT(size != -1); 1252 ASSERT(size != -1);
1254 return size; 1253 return size;
1255 } 1254 }
1256 1255
1257 1256
1258 void FlowGraphCompiler::EmitOptimizedInstanceCall( 1257 void FlowGraphCompiler::EmitOptimizedInstanceCall(
1259 ExternalLabel* target_label, 1258 const StubEntry& stub_entry,
1260 const ICData& ic_data, 1259 const ICData& ic_data,
1261 intptr_t argument_count, 1260 intptr_t argument_count,
1262 intptr_t deopt_id, 1261 intptr_t deopt_id,
1263 intptr_t token_pos, 1262 intptr_t token_pos,
1264 LocationSummary* locs) { 1263 LocationSummary* locs) {
1265 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0); 1264 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0);
1266 // Each ICData propagated from unoptimized to optimized code contains the 1265 // Each ICData propagated from unoptimized to optimized code contains the
1267 // function that corresponds to the Dart function of that IC call. Due 1266 // function that corresponds to the Dart function of that IC call. Due
1268 // to inlining in optimized code, that function may not correspond to the 1267 // to inlining in optimized code, that function may not correspond to the
1269 // top-level function (parsed_function().function()) which could be 1268 // top-level function (parsed_function().function()) which could be
1270 // reoptimized and which counter needs to be incremented. 1269 // reoptimized and which counter needs to be incremented.
1271 // Pass the function explicitly, it is used in IC stub. 1270 // Pass the function explicitly, it is used in IC stub.
1272 __ LoadObject(EDI, parsed_function().function()); 1271 __ LoadObject(EDI, parsed_function().function());
1273 __ LoadObject(ECX, ic_data); 1272 __ LoadObject(ECX, ic_data);
1274 GenerateDartCall(deopt_id, 1273 GenerateDartCall(deopt_id,
1275 token_pos, 1274 token_pos,
1276 target_label, 1275 stub_entry,
1277 RawPcDescriptors::kIcCall, 1276 RawPcDescriptors::kIcCall,
1278 locs); 1277 locs);
1279 __ Drop(argument_count); 1278 __ Drop(argument_count);
1280 } 1279 }
1281 1280
1282 1281
1283 void FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label, 1282 void FlowGraphCompiler::EmitInstanceCall(const StubEntry& stub_entry,
1284 const ICData& ic_data, 1283 const ICData& ic_data,
1285 intptr_t argument_count, 1284 intptr_t argument_count,
1286 intptr_t deopt_id, 1285 intptr_t deopt_id,
1287 intptr_t token_pos, 1286 intptr_t token_pos,
1288 LocationSummary* locs) { 1287 LocationSummary* locs) {
1289 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0); 1288 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0);
1290 __ LoadObject(ECX, ic_data); 1289 __ LoadObject(ECX, ic_data);
1291 GenerateDartCall(deopt_id, 1290 GenerateDartCall(deopt_id,
1292 token_pos, 1291 token_pos,
1293 target_label, 1292 stub_entry,
1294 RawPcDescriptors::kIcCall, 1293 RawPcDescriptors::kIcCall,
1295 locs); 1294 locs);
1296 __ Drop(argument_count); 1295 __ Drop(argument_count);
1297 } 1296 }
1298 1297
1299 1298
1300 void FlowGraphCompiler::EmitMegamorphicInstanceCall( 1299 void FlowGraphCompiler::EmitMegamorphicInstanceCall(
1301 const ICData& ic_data, 1300 const ICData& ic_data,
1302 intptr_t argument_count, 1301 intptr_t argument_count,
1303 intptr_t deopt_id, 1302 intptr_t deopt_id,
1304 intptr_t token_pos, 1303 intptr_t token_pos,
1305 LocationSummary* locs) { 1304 LocationSummary* locs) {
1306 MegamorphicCacheTable* table = isolate()->megamorphic_cache_table(); 1305 MegamorphicCacheTable* table = isolate()->megamorphic_cache_table();
1307 const String& name = String::Handle(zone(), ic_data.target_name()); 1306 const String& name = String::Handle(zone(), ic_data.target_name());
1308 const Array& arguments_descriptor = 1307 const Array& arguments_descriptor =
1309 Array::ZoneHandle(zone(), ic_data.arguments_descriptor()); 1308 Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
1310 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0)); 1309 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
1311 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(), 1310 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
1312 table->Lookup(name, arguments_descriptor)); 1311 table->Lookup(name, arguments_descriptor));
1313 const Register receiverR = EDI; 1312 const Register receiverR = EDI;
1314 const Register cacheR = EBX; 1313 const Register cacheR = EBX;
1315 const Register targetR = EBX; 1314 const Register targetR = EBX;
1316 __ movl(receiverR, Address(ESP, (argument_count - 1) * kWordSize)); 1315 __ movl(receiverR, Address(ESP, (argument_count - 1) * kWordSize));
1317 __ LoadObject(cacheR, cache); 1316 __ LoadObject(cacheR, cache);
1318 1317
1319 if (FLAG_use_megamorphic_stub) { 1318 if (FLAG_use_megamorphic_stub) {
1320 __ call(&StubCode::MegamorphicLookupLabel()); 1319 __ Call(*StubCode::MegamorphicLookup_entry());
1321 } else { 1320 } else {
1322 StubCode::EmitMegamorphicLookup(assembler(), receiverR, cacheR, targetR); 1321 StubCode::EmitMegamorphicLookup(assembler(), receiverR, cacheR, targetR);
1323 } 1322 }
1324 1323
1325 __ LoadObject(ECX, ic_data); 1324 __ LoadObject(ECX, ic_data);
1326 __ LoadObject(EDX, arguments_descriptor); 1325 __ LoadObject(EDX, arguments_descriptor);
1327 __ call(targetR); 1326 __ call(targetR);
1328 AddCurrentDescriptor(RawPcDescriptors::kOther, 1327 AddCurrentDescriptor(RawPcDescriptors::kOther,
1329 Isolate::kNoDeoptId, token_pos); 1328 Isolate::kNoDeoptId, token_pos);
1330 RecordSafepoint(locs); 1329 RecordSafepoint(locs);
(...skipping 14 matching lines...) Expand all
1345 const Array& arguments_descriptor, 1344 const Array& arguments_descriptor,
1346 intptr_t argument_count, 1345 intptr_t argument_count,
1347 intptr_t deopt_id, 1346 intptr_t deopt_id,
1348 intptr_t token_pos, 1347 intptr_t token_pos,
1349 LocationSummary* locs) { 1348 LocationSummary* locs) {
1350 __ LoadObject(EDX, arguments_descriptor); 1349 __ LoadObject(EDX, arguments_descriptor);
1351 // Do not use the code from the function, but let the code be patched so that 1350 // Do not use the code from the function, but let the code be patched so that
1352 // we can record the outgoing edges to other code. 1351 // we can record the outgoing edges to other code.
1353 GenerateDartCall(deopt_id, 1352 GenerateDartCall(deopt_id,
1354 token_pos, 1353 token_pos,
1355 &StubCode::CallStaticFunctionLabel(), 1354 *StubCode::CallStaticFunction_entry(),
1356 RawPcDescriptors::kOther, 1355 RawPcDescriptors::kOther,
1357 locs); 1356 locs);
1358 AddStaticCallTarget(function); 1357 AddStaticCallTarget(function);
1359 __ Drop(argument_count); 1358 __ Drop(argument_count);
1360 } 1359 }
1361 1360
1362 1361
1363 Condition FlowGraphCompiler::EmitEqualityRegConstCompare( 1362 Condition FlowGraphCompiler::EmitEqualityRegConstCompare(
1364 Register reg, 1363 Register reg,
1365 const Object& obj, 1364 const Object& obj,
1366 bool needs_number_check, 1365 bool needs_number_check,
1367 intptr_t token_pos) { 1366 intptr_t token_pos) {
1368 ASSERT(!needs_number_check || 1367 ASSERT(!needs_number_check ||
1369 (!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint())); 1368 (!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint()));
1370 1369
1371 if (obj.IsSmi() && (Smi::Cast(obj).Value() == 0)) { 1370 if (obj.IsSmi() && (Smi::Cast(obj).Value() == 0)) {
1372 ASSERT(!needs_number_check); 1371 ASSERT(!needs_number_check);
1373 __ testl(reg, reg); 1372 __ testl(reg, reg);
1374 return EQUAL; 1373 return EQUAL;
1375 } 1374 }
1376 1375
1377 if (needs_number_check) { 1376 if (needs_number_check) {
1378 __ pushl(reg); 1377 __ pushl(reg);
1379 __ PushObject(obj); 1378 __ PushObject(obj);
1380 if (is_optimizing()) { 1379 if (is_optimizing()) {
1381 __ call(&StubCode::OptimizedIdenticalWithNumberCheckLabel()); 1380 __ Call(*StubCode::OptimizedIdenticalWithNumberCheck_entry());
1382 } else { 1381 } else {
1383 __ call(&StubCode::UnoptimizedIdenticalWithNumberCheckLabel()); 1382 __ Call(*StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
1384 } 1383 }
1385 if (token_pos != Scanner::kNoSourcePos) { 1384 if (token_pos != Scanner::kNoSourcePos) {
1386 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, 1385 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
1387 Isolate::kNoDeoptId, 1386 Isolate::kNoDeoptId,
1388 token_pos); 1387 token_pos);
1389 } 1388 }
1390 // Stub returns result in flags (result of a cmpl, we need ZF computed). 1389 // Stub returns result in flags (result of a cmpl, we need ZF computed).
1391 __ popl(reg); // Discard constant. 1390 __ popl(reg); // Discard constant.
1392 __ popl(reg); // Restore 'reg'. 1391 __ popl(reg); // Restore 'reg'.
1393 } else { 1392 } else {
1394 __ CompareObject(reg, obj); 1393 __ CompareObject(reg, obj);
1395 } 1394 }
1396 return EQUAL; 1395 return EQUAL;
1397 } 1396 }
1398 1397
1399 1398
1400 Condition FlowGraphCompiler::EmitEqualityRegRegCompare(Register left, 1399 Condition FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
1401 Register right, 1400 Register right,
1402 bool needs_number_check, 1401 bool needs_number_check,
1403 intptr_t token_pos) { 1402 intptr_t token_pos) {
1404 if (needs_number_check) { 1403 if (needs_number_check) {
1405 __ pushl(left); 1404 __ pushl(left);
1406 __ pushl(right); 1405 __ pushl(right);
1407 if (is_optimizing()) { 1406 if (is_optimizing()) {
1408 __ call(&StubCode::OptimizedIdenticalWithNumberCheckLabel()); 1407 __ Call(*StubCode::OptimizedIdenticalWithNumberCheck_entry());
1409 } else { 1408 } else {
1410 __ call(&StubCode::UnoptimizedIdenticalWithNumberCheckLabel()); 1409 __ Call(*StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
1411 } 1410 }
1412 if (token_pos != Scanner::kNoSourcePos) { 1411 if (token_pos != Scanner::kNoSourcePos) {
1413 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, 1412 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
1414 Isolate::kNoDeoptId, 1413 Isolate::kNoDeoptId,
1415 token_pos); 1414 token_pos);
1416 } 1415 }
1417 // Stub returns result in flags (result of a cmpl, we need ZF computed). 1416 // Stub returns result in flags (result of a cmpl, we need ZF computed).
1418 __ popl(right); 1417 __ popl(right);
1419 __ popl(left); 1418 __ popl(left);
1420 } else { 1419 } else {
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
1531 // Jump if receiver is not Smi. 1530 // Jump if receiver is not Smi.
1532 if (kNumChecks == 1) { 1531 if (kNumChecks == 1) {
1533 __ j(NOT_ZERO, failed); 1532 __ j(NOT_ZERO, failed);
1534 } else { 1533 } else {
1535 __ j(NOT_ZERO, &after_smi_test); 1534 __ j(NOT_ZERO, &after_smi_test);
1536 } 1535 }
1537 // Do not use the code from the function, but let the code be patched so 1536 // Do not use the code from the function, but let the code be patched so
1538 // that we can record the outgoing edges to other code. 1537 // that we can record the outgoing edges to other code.
1539 GenerateDartCall(deopt_id, 1538 GenerateDartCall(deopt_id,
1540 token_index, 1539 token_index,
1541 &StubCode::CallStaticFunctionLabel(), 1540 *StubCode::CallStaticFunction_entry(),
1542 RawPcDescriptors::kOther, 1541 RawPcDescriptors::kOther,
1543 locs); 1542 locs);
1544 const Function& function = Function::Handle(zone(), ic_data.GetTargetAt(0)); 1543 const Function& function = Function::Handle(zone(), ic_data.GetTargetAt(0));
1545 AddStaticCallTarget(function); 1544 AddStaticCallTarget(function);
1546 __ Drop(argument_count); 1545 __ Drop(argument_count);
1547 if (kNumChecks > 1) { 1546 if (kNumChecks > 1) {
1548 __ jmp(match_found); 1547 __ jmp(match_found);
1549 } 1548 }
1550 } else { 1549 } else {
1551 // Receiver is Smi, but Smi is not a valid class therefore fail. 1550 // Receiver is Smi, but Smi is not a valid class therefore fail.
(...skipping 21 matching lines...) Expand all
1573 __ cmpl(EDI, Immediate(sorted[i].cid)); 1572 __ cmpl(EDI, Immediate(sorted[i].cid));
1574 if (kIsLastCheck) { 1573 if (kIsLastCheck) {
1575 __ j(NOT_EQUAL, failed); 1574 __ j(NOT_EQUAL, failed);
1576 } else { 1575 } else {
1577 __ j(NOT_EQUAL, &next_test); 1576 __ j(NOT_EQUAL, &next_test);
1578 } 1577 }
1579 // Do not use the code from the function, but let the code be patched so 1578 // Do not use the code from the function, but let the code be patched so
1580 // that we can record the outgoing edges to other code. 1579 // that we can record the outgoing edges to other code.
1581 GenerateDartCall(deopt_id, 1580 GenerateDartCall(deopt_id,
1582 token_index, 1581 token_index,
1583 &StubCode::CallStaticFunctionLabel(), 1582 *StubCode::CallStaticFunction_entry(),
1584 RawPcDescriptors::kOther, 1583 RawPcDescriptors::kOther,
1585 locs); 1584 locs);
1586 const Function& function = *sorted[i].target; 1585 const Function& function = *sorted[i].target;
1587 AddStaticCallTarget(function); 1586 AddStaticCallTarget(function);
1588 __ Drop(argument_count); 1587 __ Drop(argument_count);
1589 if (!kIsLastCheck) { 1588 if (!kIsLastCheck) {
1590 __ jmp(match_found); 1589 __ jmp(match_found);
1591 } 1590 }
1592 __ Bind(&next_test); 1591 __ Bind(&next_test);
1593 } 1592 }
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
1854 __ movups(reg, Address(ESP, 0)); 1853 __ movups(reg, Address(ESP, 0));
1855 __ addl(ESP, Immediate(kFpuRegisterSize)); 1854 __ addl(ESP, Immediate(kFpuRegisterSize));
1856 } 1855 }
1857 1856
1858 1857
1859 #undef __ 1858 #undef __
1860 1859
1861 } // namespace dart 1860 } // namespace dart
1862 1861
1863 #endif // defined TARGET_ARCH_IA32 1862 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_arm64.cc ('k') | runtime/vm/flow_graph_compiler_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698