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

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

Issue 365983002: Make isolate specific stub code accessors instance methods instead (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 5 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
« no previous file with comments | « runtime/vm/flow_graph_compiler.cc ('k') | runtime/vm/flow_graph_compiler_arm64.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_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
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 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 Assembler* assem = compiler->assembler(); 164 Assembler* assem = compiler->assembler();
165 #define __ assem-> 165 #define __ assem->
166 __ Comment("Deopt stub for id %" Pd "", deopt_id()); 166 __ Comment("Deopt stub for id %" Pd "", deopt_id());
167 __ Bind(entry_label()); 167 __ Bind(entry_label());
168 if (FLAG_trap_on_deoptimization) { 168 if (FLAG_trap_on_deoptimization) {
169 __ bkpt(0); 169 __ bkpt(0);
170 } 170 }
171 171
172 ASSERT(deopt_env() != NULL); 172 ASSERT(deopt_env() != NULL);
173 173
174 __ BranchLink(&StubCode::DeoptimizeLabel()); 174 StubCode* stub_code = compiler->isolate()->stub_code();
175 __ BranchLink(&stub_code->DeoptimizeLabel());
175 set_pc_offset(assem->CodeSize()); 176 set_pc_offset(assem->CodeSize());
176 #undef __ 177 #undef __
177 } 178 }
178 179
179 180
180 #define __ assembler()-> 181 #define __ assembler()->
181 182
182 183
183 // Fall through if bool_register contains null. 184 // Fall through if bool_register contains null.
184 void FlowGraphCompiler::GenerateBoolToJump(Register bool_register, 185 void FlowGraphCompiler::GenerateBoolToJump(Register bool_register,
(...skipping 16 matching lines...) Expand all
201 TypeTestStubKind test_kind, 202 TypeTestStubKind test_kind,
202 Register instance_reg, 203 Register instance_reg,
203 Register type_arguments_reg, 204 Register type_arguments_reg,
204 Register temp_reg, 205 Register temp_reg,
205 Label* is_instance_lbl, 206 Label* is_instance_lbl,
206 Label* is_not_instance_lbl) { 207 Label* is_not_instance_lbl) {
207 ASSERT(instance_reg == R0); 208 ASSERT(instance_reg == R0);
208 ASSERT(temp_reg == kNoRegister); // Unused on ARM. 209 ASSERT(temp_reg == kNoRegister); // Unused on ARM.
209 const SubtypeTestCache& type_test_cache = 210 const SubtypeTestCache& type_test_cache =
210 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New()); 211 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New());
212 StubCode* stub_code = isolate()->stub_code();
211 __ LoadObject(R2, type_test_cache); 213 __ LoadObject(R2, type_test_cache);
212 if (test_kind == kTestTypeOneArg) { 214 if (test_kind == kTestTypeOneArg) {
213 ASSERT(type_arguments_reg == kNoRegister); 215 ASSERT(type_arguments_reg == kNoRegister);
214 __ LoadImmediate(R1, reinterpret_cast<intptr_t>(Object::null())); 216 __ LoadImmediate(R1, reinterpret_cast<intptr_t>(Object::null()));
215 __ BranchLink(&StubCode::Subtype1TestCacheLabel()); 217 __ BranchLink(&stub_code->Subtype1TestCacheLabel());
216 } else if (test_kind == kTestTypeTwoArgs) { 218 } else if (test_kind == kTestTypeTwoArgs) {
217 ASSERT(type_arguments_reg == kNoRegister); 219 ASSERT(type_arguments_reg == kNoRegister);
218 __ LoadImmediate(R1, reinterpret_cast<intptr_t>(Object::null())); 220 __ LoadImmediate(R1, reinterpret_cast<intptr_t>(Object::null()));
219 __ BranchLink(&StubCode::Subtype2TestCacheLabel()); 221 __ BranchLink(&stub_code->Subtype2TestCacheLabel());
220 } else if (test_kind == kTestTypeThreeArgs) { 222 } else if (test_kind == kTestTypeThreeArgs) {
221 ASSERT(type_arguments_reg == R1); 223 ASSERT(type_arguments_reg == R1);
222 __ BranchLink(&StubCode::Subtype3TestCacheLabel()); 224 __ BranchLink(&stub_code->Subtype3TestCacheLabel());
223 } else { 225 } else {
224 UNREACHABLE(); 226 UNREACHABLE();
225 } 227 }
226 // Result is in R1: null -> not found, otherwise Bool::True or Bool::False. 228 // Result is in R1: null -> not found, otherwise Bool::True or Bool::False.
227 GenerateBoolToJump(R1, is_instance_lbl, is_not_instance_lbl); 229 GenerateBoolToJump(R1, is_instance_lbl, is_not_instance_lbl);
228 return type_test_cache.raw(); 230 return type_test_cache.raw();
229 } 231 }
230 232
231 233
232 // Jumps to labels 'is_instance' or 'is_not_instance' respectively, if 234 // Jumps to labels 'is_instance' or 'is_not_instance' respectively, if
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 __ SmiUntag(R7); 889 __ SmiUntag(R7);
888 // Check that R8 equals R7, i.e. no named arguments passed. 890 // Check that R8 equals R7, i.e. no named arguments passed.
889 __ cmp(R8, Operand(R7)); 891 __ cmp(R8, Operand(R7));
890 __ b(&all_arguments_processed, EQ); 892 __ b(&all_arguments_processed, EQ);
891 } 893 }
892 } 894 }
893 895
894 __ Bind(&wrong_num_arguments); 896 __ Bind(&wrong_num_arguments);
895 if (function.IsClosureFunction()) { 897 if (function.IsClosureFunction()) {
896 // Invoke noSuchMethod function passing "call" as the original name. 898 // Invoke noSuchMethod function passing "call" as the original name.
899 StubCode* stub_code = isolate()->stub_code();
897 const int kNumArgsChecked = 1; 900 const int kNumArgsChecked = 1;
898 const ICData& ic_data = ICData::ZoneHandle( 901 const ICData& ic_data = ICData::ZoneHandle(
899 ICData::New(function, Symbols::Call(), Object::empty_array(), 902 ICData::New(function, Symbols::Call(), Object::empty_array(),
900 Isolate::kNoDeoptId, kNumArgsChecked)); 903 Isolate::kNoDeoptId, kNumArgsChecked));
901 __ LoadObject(R5, ic_data); 904 __ LoadObject(R5, ic_data);
902 __ LeaveDartFrame(); // The arguments are still on the stack. 905 __ LeaveDartFrame(); // The arguments are still on the stack.
903 __ Branch(&StubCode::CallNoSuchMethodFunctionLabel()); 906 __ Branch(&stub_code->CallNoSuchMethodFunctionLabel());
904 // The noSuchMethod call may return to the caller, but not here. 907 // The noSuchMethod call may return to the caller, but not here.
905 __ bkpt(0); 908 __ bkpt(0);
906 } else if (check_correct_named_args) { 909 } else if (check_correct_named_args) {
907 __ Stop("Wrong arguments"); 910 __ Stop("Wrong arguments");
908 } 911 }
909 912
910 __ Bind(&all_arguments_processed); 913 __ Bind(&all_arguments_processed);
911 // Nullify originally passed arguments only after they have been copied and 914 // Nullify originally passed arguments only after they have been copied and
912 // checked, otherwise noSuchMethod would not see their original values. 915 // checked, otherwise noSuchMethod would not see their original values.
913 // This step can be skipped in case we decide that formal parameters are 916 // This step can be skipped in case we decide that formal parameters are
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
954 __ Ret(); 957 __ Ret();
955 } 958 }
956 959
957 960
958 void FlowGraphCompiler::EmitFrameEntry() { 961 void FlowGraphCompiler::EmitFrameEntry() {
959 const Function& function = parsed_function().function(); 962 const Function& function = parsed_function().function();
960 if (CanOptimizeFunction() && 963 if (CanOptimizeFunction() &&
961 function.IsOptimizable() && 964 function.IsOptimizable() &&
962 (!is_optimizing() || may_reoptimize())) { 965 (!is_optimizing() || may_reoptimize())) {
963 const Register function_reg = R6; 966 const Register function_reg = R6;
967 StubCode* stub_code = isolate()->stub_code();
964 968
965 // The pool pointer is not setup before entering the Dart frame. 969 // The pool pointer is not setup before entering the Dart frame.
966 // Preserve PP of caller. 970 // Preserve PP of caller.
967 __ mov(R7, Operand(PP)); 971 __ mov(R7, Operand(PP));
968 // Temporarily setup pool pointer for this dart function. 972 // Temporarily setup pool pointer for this dart function.
969 __ LoadPoolPointer(); 973 __ LoadPoolPointer();
970 // Load function object from object pool. 974 // Load function object from object pool.
971 __ LoadObject(function_reg, function); // Uses PP. 975 __ LoadObject(function_reg, function); // Uses PP.
972 // Restore PP of caller. 976 // Restore PP of caller.
973 __ mov(PP, Operand(R7)); 977 __ mov(PP, Operand(R7));
974 978
975 // Patch point is after the eventually inlined function object. 979 // Patch point is after the eventually inlined function object.
976 entry_patch_pc_offset_ = assembler()->CodeSize(); 980 entry_patch_pc_offset_ = assembler()->CodeSize();
977 981
978 intptr_t threshold = FLAG_optimization_counter_threshold; 982 intptr_t threshold = FLAG_optimization_counter_threshold;
979 __ ldr(R7, FieldAddress(function_reg, 983 __ ldr(R7, FieldAddress(function_reg,
980 Function::usage_counter_offset())); 984 Function::usage_counter_offset()));
981 if (is_optimizing()) { 985 if (is_optimizing()) {
982 // Reoptimization of an optimized function is triggered by counting in 986 // Reoptimization of an optimized function is triggered by counting in
983 // IC stubs, but not at the entry of the function. 987 // IC stubs, but not at the entry of the function.
984 threshold = FLAG_reoptimization_counter_threshold; 988 threshold = FLAG_reoptimization_counter_threshold;
985 } else { 989 } else {
986 __ add(R7, R7, Operand(1)); 990 __ add(R7, R7, Operand(1));
987 __ str(R7, FieldAddress(function_reg, 991 __ str(R7, FieldAddress(function_reg,
988 Function::usage_counter_offset())); 992 Function::usage_counter_offset()));
989 } 993 }
990 __ CompareImmediate(R7, threshold); 994 __ CompareImmediate(R7, threshold);
991 ASSERT(function_reg == R6); 995 ASSERT(function_reg == R6);
992 __ Branch(&StubCode::OptimizeFunctionLabel(), GE); 996 __ Branch(&stub_code->OptimizeFunctionLabel(), GE);
993 } else if (!flow_graph().IsCompiledForOsr()) { 997 } else if (!flow_graph().IsCompiledForOsr()) {
994 entry_patch_pc_offset_ = assembler()->CodeSize(); 998 entry_patch_pc_offset_ = assembler()->CodeSize();
995 } 999 }
996 __ Comment("Enter frame"); 1000 __ Comment("Enter frame");
997 if (flow_graph().IsCompiledForOsr()) { 1001 if (flow_graph().IsCompiledForOsr()) {
998 intptr_t extra_slots = StackSize() 1002 intptr_t extra_slots = StackSize()
999 - flow_graph().num_stack_locals() 1003 - flow_graph().num_stack_locals()
1000 - flow_graph().num_copied_params(); 1004 - flow_graph().num_copied_params();
1001 ASSERT(extra_slots >= 0); 1005 ASSERT(extra_slots >= 0);
1002 __ EnterOsrFrame(extra_slots * kWordSize); 1006 __ EnterOsrFrame(extra_slots * kWordSize);
(...skipping 16 matching lines...) Expand all
1019 1023
1020 TryIntrinsify(); 1024 TryIntrinsify();
1021 1025
1022 EmitFrameEntry(); 1026 EmitFrameEntry();
1023 1027
1024 const Function& function = parsed_function().function(); 1028 const Function& function = parsed_function().function();
1025 1029
1026 const int num_fixed_params = function.num_fixed_parameters(); 1030 const int num_fixed_params = function.num_fixed_parameters();
1027 const int num_copied_params = parsed_function().num_copied_params(); 1031 const int num_copied_params = parsed_function().num_copied_params();
1028 const int num_locals = parsed_function().num_stack_locals(); 1032 const int num_locals = parsed_function().num_stack_locals();
1033 StubCode* stub_code = isolate()->stub_code();
1029 1034
1030 // We check the number of passed arguments when we have to copy them due to 1035 // We check the number of passed arguments when we have to copy them due to
1031 // the presence of optional parameters. 1036 // the presence of optional parameters.
1032 // No such checking code is generated if only fixed parameters are declared, 1037 // No such checking code is generated if only fixed parameters are declared,
1033 // unless we are in debug mode or unless we are compiling a closure. 1038 // unless we are in debug mode or unless we are compiling a closure.
1034 if (num_copied_params == 0) { 1039 if (num_copied_params == 0) {
1035 #ifdef DEBUG 1040 #ifdef DEBUG
1036 ASSERT(!parsed_function().function().HasOptionalParameters()); 1041 ASSERT(!parsed_function().function().HasOptionalParameters());
1037 const bool check_arguments = !flow_graph().IsCompiledForOsr(); 1042 const bool check_arguments = !flow_graph().IsCompiledForOsr();
1038 #else 1043 #else
(...skipping 18 matching lines...) Expand all
1057 const String& name = 1062 const String& name =
1058 String::Handle(function.IsClosureFunction() 1063 String::Handle(function.IsClosureFunction()
1059 ? Symbols::Call().raw() 1064 ? Symbols::Call().raw()
1060 : function.name()); 1065 : function.name());
1061 const int kNumArgsChecked = 1; 1066 const int kNumArgsChecked = 1;
1062 const ICData& ic_data = ICData::ZoneHandle( 1067 const ICData& ic_data = ICData::ZoneHandle(
1063 ICData::New(function, name, Object::empty_array(), 1068 ICData::New(function, name, Object::empty_array(),
1064 Isolate::kNoDeoptId, kNumArgsChecked)); 1069 Isolate::kNoDeoptId, kNumArgsChecked));
1065 __ LoadObject(R5, ic_data); 1070 __ LoadObject(R5, ic_data);
1066 __ LeaveDartFrame(); // The arguments are still on the stack. 1071 __ LeaveDartFrame(); // The arguments are still on the stack.
1067 __ Branch(&StubCode::CallNoSuchMethodFunctionLabel()); 1072 __ Branch(&stub_code->CallNoSuchMethodFunctionLabel());
1068 // The noSuchMethod call may return to the caller, but not here. 1073 // The noSuchMethod call may return to the caller, but not here.
1069 __ bkpt(0); 1074 __ bkpt(0);
1070 } else { 1075 } else {
1071 __ Stop("Wrong number of arguments"); 1076 __ Stop("Wrong number of arguments");
1072 } 1077 }
1073 __ Bind(&correct_num_arguments); 1078 __ Bind(&correct_num_arguments);
1074 } 1079 }
1075 } else if (!flow_graph().IsCompiledForOsr()) { 1080 } else if (!flow_graph().IsCompiledForOsr()) {
1076 CopyParameters(); 1081 CopyParameters();
1077 } 1082 }
(...skipping 10 matching lines...) Expand all
1088 } 1093 }
1089 } 1094 }
1090 1095
1091 VisitBlocks(); 1096 VisitBlocks();
1092 1097
1093 __ bkpt(0); 1098 __ bkpt(0);
1094 GenerateDeferredCode(); 1099 GenerateDeferredCode();
1095 // Emit function patching code. This will be swapped with the first 3 1100 // Emit function patching code. This will be swapped with the first 3
1096 // instructions at entry point. 1101 // instructions at entry point.
1097 patch_code_pc_offset_ = assembler()->CodeSize(); 1102 patch_code_pc_offset_ = assembler()->CodeSize();
1098 __ BranchPatchable(&StubCode::FixCallersTargetLabel()); 1103 __ BranchPatchable(&stub_code->FixCallersTargetLabel());
1099 1104
1100 if (is_optimizing()) { 1105 if (is_optimizing()) {
1101 lazy_deopt_pc_offset_ = assembler()->CodeSize(); 1106 lazy_deopt_pc_offset_ = assembler()->CodeSize();
1102 __ Branch(&StubCode::DeoptimizeLazyLabel()); 1107 __ Branch(&stub_code->DeoptimizeLazyLabel());
1103 } 1108 }
1104 } 1109 }
1105 1110
1106 1111
1107 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, 1112 void FlowGraphCompiler::GenerateCall(intptr_t token_pos,
1108 const ExternalLabel* label, 1113 const ExternalLabel* label,
1109 PcDescriptors::Kind kind, 1114 PcDescriptors::Kind kind,
1110 LocationSummary* locs) { 1115 LocationSummary* locs) {
1111 __ BranchLinkPatchable(label); 1116 __ BranchLinkPatchable(label);
1112 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos); 1117 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos);
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1284 } 1289 }
1285 1290
1286 1291
1287 void FlowGraphCompiler::EmitUnoptimizedStaticCall( 1292 void FlowGraphCompiler::EmitUnoptimizedStaticCall(
1288 intptr_t argument_count, 1293 intptr_t argument_count,
1289 intptr_t deopt_id, 1294 intptr_t deopt_id,
1290 intptr_t token_pos, 1295 intptr_t token_pos,
1291 LocationSummary* locs, 1296 LocationSummary* locs,
1292 const ICData& ic_data) { 1297 const ICData& ic_data) {
1293 uword label_address = 0; 1298 uword label_address = 0;
1299 StubCode* stub_code = isolate()->stub_code();
1294 if (ic_data.NumArgsTested() == 0) { 1300 if (ic_data.NumArgsTested() == 0) {
1295 label_address = StubCode::ZeroArgsUnoptimizedStaticCallEntryPoint(); 1301 label_address = stub_code->ZeroArgsUnoptimizedStaticCallEntryPoint();
1296 } else if (ic_data.NumArgsTested() == 2) { 1302 } else if (ic_data.NumArgsTested() == 2) {
1297 label_address = StubCode::TwoArgsUnoptimizedStaticCallEntryPoint(); 1303 label_address = stub_code->TwoArgsUnoptimizedStaticCallEntryPoint();
1298 } else { 1304 } else {
1299 UNIMPLEMENTED(); 1305 UNIMPLEMENTED();
1300 } 1306 }
1301 ExternalLabel target_label(label_address); 1307 ExternalLabel target_label(label_address);
1302 __ LoadImmediate(R4, 0); 1308 __ LoadImmediate(R4, 0);
1303 __ LoadObject(R5, ic_data); 1309 __ LoadObject(R5, ic_data);
1304 GenerateDartCall(deopt_id, 1310 GenerateDartCall(deopt_id,
1305 token_pos, 1311 token_pos,
1306 &target_label, 1312 &target_label,
1307 PcDescriptors::kUnoptStaticCall, 1313 PcDescriptors::kUnoptStaticCall,
1308 locs); 1314 locs);
1309 __ Drop(argument_count); 1315 __ Drop(argument_count);
1310 #if defined(DEBUG) 1316 #if defined(DEBUG)
1311 __ LoadImmediate(R4, kInvalidObjectPointer); 1317 __ LoadImmediate(R4, kInvalidObjectPointer);
1312 #endif 1318 #endif
1313 } 1319 }
1314 1320
1315 1321
1316 void FlowGraphCompiler::EmitOptimizedStaticCall( 1322 void FlowGraphCompiler::EmitOptimizedStaticCall(
1317 const Function& function, 1323 const Function& function,
1318 const Array& arguments_descriptor, 1324 const Array& arguments_descriptor,
1319 intptr_t argument_count, 1325 intptr_t argument_count,
1320 intptr_t deopt_id, 1326 intptr_t deopt_id,
1321 intptr_t token_pos, 1327 intptr_t token_pos,
1322 LocationSummary* locs) { 1328 LocationSummary* locs) {
1329 StubCode* stub_code = isolate()->stub_code();
1323 __ LoadObject(R4, arguments_descriptor); 1330 __ LoadObject(R4, arguments_descriptor);
1324 // Do not use the code from the function, but let the code be patched so that 1331 // Do not use the code from the function, but let the code be patched so that
1325 // we can record the outgoing edges to other code. 1332 // we can record the outgoing edges to other code.
1326 GenerateDartCall(deopt_id, 1333 GenerateDartCall(deopt_id,
1327 token_pos, 1334 token_pos,
1328 &StubCode::CallStaticFunctionLabel(), 1335 &stub_code->CallStaticFunctionLabel(),
1329 PcDescriptors::kOptStaticCall, 1336 PcDescriptors::kOptStaticCall,
1330 locs); 1337 locs);
1331 AddStaticCallTarget(function); 1338 AddStaticCallTarget(function);
1332 __ Drop(argument_count); 1339 __ Drop(argument_count);
1333 } 1340 }
1334 1341
1335 1342
1336 void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg, 1343 void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg,
1337 const Object& obj, 1344 const Object& obj,
1338 bool needs_number_check, 1345 bool needs_number_check,
1339 intptr_t token_pos) { 1346 intptr_t token_pos) {
1340 if (needs_number_check) { 1347 if (needs_number_check) {
1348 StubCode* stub_code = isolate()->stub_code();
1341 ASSERT(!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint()); 1349 ASSERT(!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint());
1342 __ Push(reg); 1350 __ Push(reg);
1343 __ PushObject(obj); 1351 __ PushObject(obj);
1344 if (is_optimizing()) { 1352 if (is_optimizing()) {
1345 __ BranchLinkPatchable( 1353 __ BranchLinkPatchable(
1346 &StubCode::OptimizedIdenticalWithNumberCheckLabel()); 1354 &stub_code->OptimizedIdenticalWithNumberCheckLabel());
1347 } else { 1355 } else {
1348 __ BranchLinkPatchable( 1356 __ BranchLinkPatchable(
1349 &StubCode::UnoptimizedIdenticalWithNumberCheckLabel()); 1357 &stub_code->UnoptimizedIdenticalWithNumberCheckLabel());
1350 } 1358 }
1351 if (token_pos != Scanner::kNoSourcePos) { 1359 if (token_pos != Scanner::kNoSourcePos) {
1352 AddCurrentDescriptor(PcDescriptors::kRuntimeCall, 1360 AddCurrentDescriptor(PcDescriptors::kRuntimeCall,
1353 Isolate::kNoDeoptId, 1361 Isolate::kNoDeoptId,
1354 token_pos); 1362 token_pos);
1355 } 1363 }
1356 __ Drop(1); // Discard constant. 1364 __ Drop(1); // Discard constant.
1357 __ Pop(reg); // Restore 'reg'. 1365 __ Pop(reg); // Restore 'reg'.
1358 return; 1366 return;
1359 } 1367 }
1360 1368
1361 __ CompareObject(reg, obj); 1369 __ CompareObject(reg, obj);
1362 } 1370 }
1363 1371
1364 1372
1365 void FlowGraphCompiler::EmitEqualityRegRegCompare(Register left, 1373 void FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
1366 Register right, 1374 Register right,
1367 bool needs_number_check, 1375 bool needs_number_check,
1368 intptr_t token_pos) { 1376 intptr_t token_pos) {
1369 if (needs_number_check) { 1377 if (needs_number_check) {
1378 StubCode* stub_code = isolate()->stub_code();
1370 __ Push(left); 1379 __ Push(left);
1371 __ Push(right); 1380 __ Push(right);
1372 if (is_optimizing()) { 1381 if (is_optimizing()) {
1373 __ BranchLinkPatchable( 1382 __ BranchLinkPatchable(
1374 &StubCode::OptimizedIdenticalWithNumberCheckLabel()); 1383 &stub_code->OptimizedIdenticalWithNumberCheckLabel());
1375 } else { 1384 } else {
1376 __ LoadImmediate(R4, 0); 1385 __ LoadImmediate(R4, 0);
1377 __ LoadImmediate(R5, 0); 1386 __ LoadImmediate(R5, 0);
1378 __ BranchLinkPatchable( 1387 __ BranchLinkPatchable(
1379 &StubCode::UnoptimizedIdenticalWithNumberCheckLabel()); 1388 &stub_code->UnoptimizedIdenticalWithNumberCheckLabel());
1380 } 1389 }
1381 if (token_pos != Scanner::kNoSourcePos) { 1390 if (token_pos != Scanner::kNoSourcePos) {
1382 AddCurrentDescriptor(PcDescriptors::kRuntimeCall, 1391 AddCurrentDescriptor(PcDescriptors::kRuntimeCall,
1383 Isolate::kNoDeoptId, 1392 Isolate::kNoDeoptId,
1384 token_pos); 1393 token_pos);
1385 } 1394 }
1386 #if defined(DEBUG) 1395 #if defined(DEBUG)
1387 if (!is_optimizing()) { 1396 if (!is_optimizing()) {
1388 // Do this *after* adding the pc descriptor! 1397 // Do this *after* adding the pc descriptor!
1389 __ LoadImmediate(R4, kInvalidObjectPointer); 1398 __ LoadImmediate(R4, kInvalidObjectPointer);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1481 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); 1490 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
1482 Label match_found; 1491 Label match_found;
1483 const intptr_t len = ic_data.NumberOfChecks(); 1492 const intptr_t len = ic_data.NumberOfChecks();
1484 GrowableArray<CidTarget> sorted(len); 1493 GrowableArray<CidTarget> sorted(len);
1485 SortICDataByCount(ic_data, &sorted); 1494 SortICDataByCount(ic_data, &sorted);
1486 ASSERT(class_id_reg != R4); 1495 ASSERT(class_id_reg != R4);
1487 ASSERT(len > 0); // Why bother otherwise. 1496 ASSERT(len > 0); // Why bother otherwise.
1488 const Array& arguments_descriptor = 1497 const Array& arguments_descriptor =
1489 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, 1498 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
1490 argument_names)); 1499 argument_names));
1500 StubCode* stub_code = isolate()->stub_code();
1501
1491 __ LoadObject(R4, arguments_descriptor); 1502 __ LoadObject(R4, arguments_descriptor);
1492 for (intptr_t i = 0; i < len; i++) { 1503 for (intptr_t i = 0; i < len; i++) {
1493 const bool is_last_check = (i == (len - 1)); 1504 const bool is_last_check = (i == (len - 1));
1494 Label next_test; 1505 Label next_test;
1495 __ CompareImmediate(class_id_reg, sorted[i].cid); 1506 __ CompareImmediate(class_id_reg, sorted[i].cid);
1496 if (is_last_check) { 1507 if (is_last_check) {
1497 __ b(deopt, NE); 1508 __ b(deopt, NE);
1498 } else { 1509 } else {
1499 __ b(&next_test, NE); 1510 __ b(&next_test, NE);
1500 } 1511 }
1501 // Do not use the code from the function, but let the code be patched so 1512 // Do not use the code from the function, but let the code be patched so
1502 // that we can record the outgoing edges to other code. 1513 // that we can record the outgoing edges to other code.
1503 GenerateDartCall(deopt_id, 1514 GenerateDartCall(deopt_id,
1504 token_index, 1515 token_index,
1505 &StubCode::CallStaticFunctionLabel(), 1516 &stub_code->CallStaticFunctionLabel(),
1506 PcDescriptors::kOptStaticCall, 1517 PcDescriptors::kOptStaticCall,
1507 locs); 1518 locs);
1508 const Function& function = *sorted[i].target; 1519 const Function& function = *sorted[i].target;
1509 AddStaticCallTarget(function); 1520 AddStaticCallTarget(function);
1510 __ Drop(argument_count); 1521 __ Drop(argument_count);
1511 if (!is_last_check) { 1522 if (!is_last_check) {
1512 __ b(&match_found); 1523 __ b(&match_found);
1513 } 1524 }
1514 __ Bind(&next_test); 1525 __ Bind(&next_test);
1515 } 1526 }
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
1762 DRegister dreg = EvenDRegisterOf(reg); 1773 DRegister dreg = EvenDRegisterOf(reg);
1763 __ vldrd(dreg, Address(SP, kDoubleSize, Address::PostIndex)); 1774 __ vldrd(dreg, Address(SP, kDoubleSize, Address::PostIndex));
1764 } 1775 }
1765 1776
1766 1777
1767 #undef __ 1778 #undef __
1768 1779
1769 } // namespace dart 1780 } // namespace dart
1770 1781
1771 #endif // defined TARGET_ARCH_ARM 1782 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler.cc ('k') | runtime/vm/flow_graph_compiler_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698