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

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

Issue 1247783002: Make array allocation stub shared between isolates. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 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
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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_ARM64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64.
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
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 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 Assembler* assem = compiler->assembler(); 179 Assembler* assem = compiler->assembler();
180 #define __ assem-> 180 #define __ assem->
181 __ Comment("%s", Name()); 181 __ Comment("%s", Name());
182 __ Bind(entry_label()); 182 __ Bind(entry_label());
183 if (FLAG_trap_on_deoptimization) { 183 if (FLAG_trap_on_deoptimization) {
184 __ brk(0); 184 __ brk(0);
185 } 185 }
186 186
187 ASSERT(deopt_env() != NULL); 187 ASSERT(deopt_env() != NULL);
188 188
189 StubCode* stub_code = compiler->isolate()->stub_code(); 189 __ BranchLink(&StubCode::DeoptimizeLabel(), PP);
190 __ BranchLink(&stub_code->DeoptimizeLabel(), PP);
191 set_pc_offset(assem->CodeSize()); 190 set_pc_offset(assem->CodeSize());
192 #undef __ 191 #undef __
193 } 192 }
194 193
195 194
196 #define __ assembler()-> 195 #define __ assembler()->
197 196
198 197
199 // Fall through if bool_register contains null. 198 // Fall through if bool_register contains null.
200 void FlowGraphCompiler::GenerateBoolToJump(Register bool_register, 199 void FlowGraphCompiler::GenerateBoolToJump(Register bool_register,
(...skipping 15 matching lines...) Expand all
216 TypeTestStubKind test_kind, 215 TypeTestStubKind test_kind,
217 Register instance_reg, 216 Register instance_reg,
218 Register type_arguments_reg, 217 Register type_arguments_reg,
219 Register temp_reg, 218 Register temp_reg,
220 Label* is_instance_lbl, 219 Label* is_instance_lbl,
221 Label* is_not_instance_lbl) { 220 Label* is_not_instance_lbl) {
222 ASSERT(instance_reg == R0); 221 ASSERT(instance_reg == R0);
223 ASSERT(temp_reg == kNoRegister); // Unused on ARM. 222 ASSERT(temp_reg == kNoRegister); // Unused on ARM.
224 const SubtypeTestCache& type_test_cache = 223 const SubtypeTestCache& type_test_cache =
225 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New()); 224 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New());
226 StubCode* stub_code = isolate()->stub_code();
227 __ LoadUniqueObject(R2, type_test_cache, PP); 225 __ LoadUniqueObject(R2, type_test_cache, PP);
228 if (test_kind == kTestTypeOneArg) { 226 if (test_kind == kTestTypeOneArg) {
229 ASSERT(type_arguments_reg == kNoRegister); 227 ASSERT(type_arguments_reg == kNoRegister);
230 __ LoadObject(R1, Object::null_object(), PP); 228 __ LoadObject(R1, Object::null_object(), PP);
231 __ BranchLink(&stub_code->Subtype1TestCacheLabel(), PP); 229 __ BranchLink(&StubCode::Subtype1TestCacheLabel(), PP);
232 } else if (test_kind == kTestTypeTwoArgs) { 230 } else if (test_kind == kTestTypeTwoArgs) {
233 ASSERT(type_arguments_reg == kNoRegister); 231 ASSERT(type_arguments_reg == kNoRegister);
234 __ LoadObject(R1, Object::null_object(), PP); 232 __ LoadObject(R1, Object::null_object(), PP);
235 __ BranchLink(&stub_code->Subtype2TestCacheLabel(), PP); 233 __ BranchLink(&StubCode::Subtype2TestCacheLabel(), PP);
236 } else if (test_kind == kTestTypeThreeArgs) { 234 } else if (test_kind == kTestTypeThreeArgs) {
237 ASSERT(type_arguments_reg == R1); 235 ASSERT(type_arguments_reg == R1);
238 __ BranchLink(&stub_code->Subtype3TestCacheLabel(), PP); 236 __ BranchLink(&StubCode::Subtype3TestCacheLabel(), PP);
239 } else { 237 } else {
240 UNREACHABLE(); 238 UNREACHABLE();
241 } 239 }
242 // Result is in R1: null -> not found, otherwise Bool::True or Bool::False. 240 // Result is in R1: null -> not found, otherwise Bool::True or Bool::False.
243 GenerateBoolToJump(R1, is_instance_lbl, is_not_instance_lbl); 241 GenerateBoolToJump(R1, is_instance_lbl, is_not_instance_lbl);
244 return type_test_cache.raw(); 242 return type_test_cache.raw();
245 } 243 }
246 244
247 245
248 // Jumps to labels 'is_instance' or 'is_not_instance' respectively, if 246 // Jumps to labels 'is_instance' or 'is_not_instance' respectively, if
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after
911 __ SmiUntag(R7); 909 __ SmiUntag(R7);
912 // Check that R8 equals R7, i.e. no named arguments passed. 910 // Check that R8 equals R7, i.e. no named arguments passed.
913 __ CompareRegisters(R8, R7); 911 __ CompareRegisters(R8, R7);
914 __ b(&all_arguments_processed, EQ); 912 __ b(&all_arguments_processed, EQ);
915 } 913 }
916 } 914 }
917 915
918 __ Bind(&wrong_num_arguments); 916 __ Bind(&wrong_num_arguments);
919 if (function.IsClosureFunction()) { 917 if (function.IsClosureFunction()) {
920 __ LeaveDartFrame(); // The arguments are still on the stack. 918 __ LeaveDartFrame(); // The arguments are still on the stack.
921 __ BranchPatchable( 919 __ BranchPatchable(&StubCode::CallClosureNoSuchMethodLabel());
922 &isolate()->stub_code()->CallClosureNoSuchMethodLabel());
923 // The noSuchMethod call may return to the caller, but not here. 920 // The noSuchMethod call may return to the caller, but not here.
924 } else if (check_correct_named_args) { 921 } else if (check_correct_named_args) {
925 __ Stop("Wrong arguments"); 922 __ Stop("Wrong arguments");
926 } 923 }
927 924
928 __ Bind(&all_arguments_processed); 925 __ Bind(&all_arguments_processed);
929 // Nullify originally passed arguments only after they have been copied and 926 // Nullify originally passed arguments only after they have been copied and
930 // checked, otherwise noSuchMethod would not see their original values. 927 // checked, otherwise noSuchMethod would not see their original values.
931 // This step can be skipped in case we decide that formal parameters are 928 // This step can be skipped in case we decide that formal parameters are
932 // implicitly final, since garbage collecting the unmodified value is not 929 // implicitly final, since garbage collecting the unmodified value is not
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
973 } 970 }
974 971
975 972
976 void FlowGraphCompiler::EmitFrameEntry() { 973 void FlowGraphCompiler::EmitFrameEntry() {
977 const Function& function = parsed_function().function(); 974 const Function& function = parsed_function().function();
978 Register new_pp = kNoPP; 975 Register new_pp = kNoPP;
979 if (CanOptimizeFunction() && 976 if (CanOptimizeFunction() &&
980 function.IsOptimizable() && 977 function.IsOptimizable() &&
981 (!is_optimizing() || may_reoptimize())) { 978 (!is_optimizing() || may_reoptimize())) {
982 const Register function_reg = R6; 979 const Register function_reg = R6;
983 StubCode* stub_code = isolate()->stub_code();
984 new_pp = R13; 980 new_pp = R13;
985 981
986 // Set up pool pointer in new_pp. 982 // Set up pool pointer in new_pp.
987 __ LoadPoolPointer(new_pp); 983 __ LoadPoolPointer(new_pp);
988 984
989 // Load function object using the callee's pool pointer. 985 // Load function object using the callee's pool pointer.
990 __ LoadObject(function_reg, function, new_pp); 986 __ LoadObject(function_reg, function, new_pp);
991 987
992 // Patch point is after the eventually inlined function object. 988 // Patch point is after the eventually inlined function object.
993 entry_patch_pc_offset_ = assembler()->CodeSize(); 989 entry_patch_pc_offset_ = assembler()->CodeSize();
994 990
995 __ LoadFieldFromOffset( 991 __ LoadFieldFromOffset(
996 R7, function_reg, Function::usage_counter_offset(), new_pp, kWord); 992 R7, function_reg, Function::usage_counter_offset(), new_pp, kWord);
997 // Reoptimization of an optimized function is triggered by counting in 993 // Reoptimization of an optimized function is triggered by counting in
998 // IC stubs, but not at the entry of the function. 994 // IC stubs, but not at the entry of the function.
999 if (!is_optimizing()) { 995 if (!is_optimizing()) {
1000 __ add(R7, R7, Operand(1)); 996 __ add(R7, R7, Operand(1));
1001 __ StoreFieldToOffset( 997 __ StoreFieldToOffset(
1002 R7, function_reg, Function::usage_counter_offset(), new_pp, kWord); 998 R7, function_reg, Function::usage_counter_offset(), new_pp, kWord);
1003 } 999 }
1004 __ CompareImmediate(R7, GetOptimizationThreshold(), new_pp); 1000 __ CompareImmediate(R7, GetOptimizationThreshold(), new_pp);
1005 ASSERT(function_reg == R6); 1001 ASSERT(function_reg == R6);
1006 Label dont_optimize; 1002 Label dont_optimize;
1007 __ b(&dont_optimize, LT); 1003 __ b(&dont_optimize, LT);
1008 __ Branch(&stub_code->OptimizeFunctionLabel(), new_pp); 1004 __ Branch(&StubCode::OptimizeFunctionLabel(), new_pp);
1009 __ Bind(&dont_optimize); 1005 __ Bind(&dont_optimize);
1010 } else if (!flow_graph().IsCompiledForOsr()) { 1006 } else if (!flow_graph().IsCompiledForOsr()) {
1011 // We have to load the PP here too because a load of an external label 1007 // We have to load the PP here too because a load of an external label
1012 // may be patched at the AddCurrentDescriptor below. 1008 // may be patched at the AddCurrentDescriptor below.
1013 new_pp = R13; 1009 new_pp = R13;
1014 1010
1015 // Set up pool pointer in new_pp. 1011 // Set up pool pointer in new_pp.
1016 __ LoadPoolPointer(new_pp); 1012 __ LoadPoolPointer(new_pp);
1017 1013
1018 entry_patch_pc_offset_ = assembler()->CodeSize(); 1014 entry_patch_pc_offset_ = assembler()->CodeSize();
(...skipping 24 matching lines...) Expand all
1043 1039
1044 TryIntrinsify(); 1040 TryIntrinsify();
1045 1041
1046 EmitFrameEntry(); 1042 EmitFrameEntry();
1047 1043
1048 const Function& function = parsed_function().function(); 1044 const Function& function = parsed_function().function();
1049 1045
1050 const int num_fixed_params = function.num_fixed_parameters(); 1046 const int num_fixed_params = function.num_fixed_parameters();
1051 const int num_copied_params = parsed_function().num_copied_params(); 1047 const int num_copied_params = parsed_function().num_copied_params();
1052 const int num_locals = parsed_function().num_stack_locals(); 1048 const int num_locals = parsed_function().num_stack_locals();
1053 StubCode* stub_code = isolate()->stub_code();
1054 1049
1055 // We check the number of passed arguments when we have to copy them due to 1050 // We check the number of passed arguments when we have to copy them due to
1056 // the presence of optional parameters. 1051 // the presence of optional parameters.
1057 // No such checking code is generated if only fixed parameters are declared, 1052 // No such checking code is generated if only fixed parameters are declared,
1058 // unless we are in debug mode or unless we are compiling a closure. 1053 // unless we are in debug mode or unless we are compiling a closure.
1059 if (num_copied_params == 0) { 1054 if (num_copied_params == 0) {
1060 #ifdef DEBUG 1055 #ifdef DEBUG
1061 ASSERT(!parsed_function().function().HasOptionalParameters()); 1056 ASSERT(!parsed_function().function().HasOptionalParameters());
1062 const bool check_arguments = !flow_graph().IsCompiledForOsr(); 1057 const bool check_arguments = !flow_graph().IsCompiledForOsr();
1063 #else 1058 #else
1064 const bool check_arguments = 1059 const bool check_arguments =
1065 function.IsClosureFunction() && !flow_graph().IsCompiledForOsr(); 1060 function.IsClosureFunction() && !flow_graph().IsCompiledForOsr();
1066 #endif 1061 #endif
1067 if (check_arguments) { 1062 if (check_arguments) {
1068 __ Comment("Check argument count"); 1063 __ Comment("Check argument count");
1069 // Check that exactly num_fixed arguments are passed in. 1064 // Check that exactly num_fixed arguments are passed in.
1070 Label correct_num_arguments, wrong_num_arguments; 1065 Label correct_num_arguments, wrong_num_arguments;
1071 __ LoadFieldFromOffset(R0, R4, ArgumentsDescriptor::count_offset(), PP); 1066 __ LoadFieldFromOffset(R0, R4, ArgumentsDescriptor::count_offset(), PP);
1072 __ CompareImmediate(R0, Smi::RawValue(num_fixed_params), PP); 1067 __ CompareImmediate(R0, Smi::RawValue(num_fixed_params), PP);
1073 __ b(&wrong_num_arguments, NE); 1068 __ b(&wrong_num_arguments, NE);
1074 __ LoadFieldFromOffset(R1, R4, 1069 __ LoadFieldFromOffset(R1, R4,
1075 ArgumentsDescriptor::positional_count_offset(), PP); 1070 ArgumentsDescriptor::positional_count_offset(), PP);
1076 __ CompareRegisters(R0, R1); 1071 __ CompareRegisters(R0, R1);
1077 __ b(&correct_num_arguments, EQ); 1072 __ b(&correct_num_arguments, EQ);
1078 __ Bind(&wrong_num_arguments); 1073 __ Bind(&wrong_num_arguments);
1079 if (function.IsClosureFunction()) { 1074 if (function.IsClosureFunction()) {
1080 __ LeaveDartFrame(); // The arguments are still on the stack. 1075 __ LeaveDartFrame(); // The arguments are still on the stack.
1081 __ BranchPatchable( 1076 __ BranchPatchable(&StubCode::CallClosureNoSuchMethodLabel());
1082 &isolate()->stub_code()->CallClosureNoSuchMethodLabel());
1083 // The noSuchMethod call may return to the caller, but not here. 1077 // The noSuchMethod call may return to the caller, but not here.
1084 } else { 1078 } else {
1085 __ Stop("Wrong number of arguments"); 1079 __ Stop("Wrong number of arguments");
1086 } 1080 }
1087 __ Bind(&correct_num_arguments); 1081 __ Bind(&correct_num_arguments);
1088 } 1082 }
1089 } else if (!flow_graph().IsCompiledForOsr()) { 1083 } else if (!flow_graph().IsCompiledForOsr()) {
1090 CopyParameters(); 1084 CopyParameters();
1091 } 1085 }
1092 1086
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1128 } 1122 }
1129 1123
1130 VisitBlocks(); 1124 VisitBlocks();
1131 1125
1132 __ brk(0); 1126 __ brk(0);
1133 GenerateDeferredCode(); 1127 GenerateDeferredCode();
1134 1128
1135 // Emit function patching code. This will be swapped with the first 3 1129 // Emit function patching code. This will be swapped with the first 3
1136 // instructions at entry point. 1130 // instructions at entry point.
1137 patch_code_pc_offset_ = assembler()->CodeSize(); 1131 patch_code_pc_offset_ = assembler()->CodeSize();
1138 __ BranchPatchable(&stub_code->FixCallersTargetLabel()); 1132 __ BranchPatchable(&StubCode::FixCallersTargetLabel());
1139 1133
1140 if (is_optimizing()) { 1134 if (is_optimizing()) {
1141 lazy_deopt_pc_offset_ = assembler()->CodeSize(); 1135 lazy_deopt_pc_offset_ = assembler()->CodeSize();
1142 __ BranchPatchable(&stub_code->DeoptimizeLazyLabel()); 1136 __ BranchPatchable(&StubCode::DeoptimizeLazyLabel());
1143 } 1137 }
1144 } 1138 }
1145 1139
1146 1140
1147 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, 1141 void FlowGraphCompiler::GenerateCall(intptr_t token_pos,
1148 const ExternalLabel* label, 1142 const ExternalLabel* label,
1149 RawPcDescriptors::Kind kind, 1143 RawPcDescriptors::Kind kind,
1150 LocationSummary* locs) { 1144 LocationSummary* locs) {
1151 __ BranchLinkPatchable(label); 1145 __ BranchLinkPatchable(label);
1152 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos); 1146 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos);
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1270 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0)); 1264 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
1271 const MegamorphicCache& cache = 1265 const MegamorphicCache& cache =
1272 MegamorphicCache::ZoneHandle(table->Lookup(name, arguments_descriptor)); 1266 MegamorphicCache::ZoneHandle(table->Lookup(name, arguments_descriptor));
1273 const Register receiverR = R0; 1267 const Register receiverR = R0;
1274 const Register cacheR = R1; 1268 const Register cacheR = R1;
1275 const Register targetR = R1; 1269 const Register targetR = R1;
1276 __ LoadFromOffset(receiverR, SP, (argument_count - 1) * kWordSize, PP); 1270 __ LoadFromOffset(receiverR, SP, (argument_count - 1) * kWordSize, PP);
1277 __ LoadObject(cacheR, cache, PP); 1271 __ LoadObject(cacheR, cache, PP);
1278 1272
1279 if (FLAG_use_megamorphic_stub) { 1273 if (FLAG_use_megamorphic_stub) {
1280 StubCode* stub_code = isolate()->stub_code(); 1274 __ BranchLink(&StubCode::MegamorphicLookupLabel(), PP);
1281 __ BranchLink(&stub_code->MegamorphicLookupLabel(), PP);
1282 } else { 1275 } else {
1283 StubCode::EmitMegamorphicLookup(assembler(), receiverR, cacheR, targetR); 1276 StubCode::EmitMegamorphicLookup(assembler(), receiverR, cacheR, targetR);
1284 } 1277 }
1285 __ LoadObject(R5, ic_data, PP); 1278 __ LoadObject(R5, ic_data, PP);
1286 __ LoadObject(R4, arguments_descriptor, PP); 1279 __ LoadObject(R4, arguments_descriptor, PP);
1287 __ blr(targetR); 1280 __ blr(targetR);
1288 AddCurrentDescriptor(RawPcDescriptors::kOther, 1281 AddCurrentDescriptor(RawPcDescriptors::kOther,
1289 Isolate::kNoDeoptId, token_pos); 1282 Isolate::kNoDeoptId, token_pos);
1290 RecordSafepoint(locs); 1283 RecordSafepoint(locs);
1291 const intptr_t deopt_id_after = Isolate::ToDeoptAfter(deopt_id); 1284 const intptr_t deopt_id_after = Isolate::ToDeoptAfter(deopt_id);
1292 if (is_optimizing()) { 1285 if (is_optimizing()) {
1293 AddDeoptIndexAtCall(deopt_id_after, token_pos); 1286 AddDeoptIndexAtCall(deopt_id_after, token_pos);
1294 } else { 1287 } else {
1295 // Add deoptimization continuation point after the call and before the 1288 // Add deoptimization continuation point after the call and before the
1296 // arguments are removed. 1289 // arguments are removed.
1297 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos); 1290 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
1298 } 1291 }
1299 __ Drop(argument_count); 1292 __ Drop(argument_count);
1300 } 1293 }
1301 1294
1302 1295
1303 void FlowGraphCompiler::EmitUnoptimizedStaticCall( 1296 void FlowGraphCompiler::EmitUnoptimizedStaticCall(
1304 intptr_t argument_count, 1297 intptr_t argument_count,
1305 intptr_t deopt_id, 1298 intptr_t deopt_id,
1306 intptr_t token_pos, 1299 intptr_t token_pos,
1307 LocationSummary* locs, 1300 LocationSummary* locs,
1308 const ICData& ic_data) { 1301 const ICData& ic_data) {
1309 StubCode* stub_code = isolate()->stub_code();
1310 const uword label_address = 1302 const uword label_address =
1311 stub_code->UnoptimizedStaticCallEntryPoint(ic_data.NumArgsTested()); 1303 StubCode::UnoptimizedStaticCallEntryPoint(ic_data.NumArgsTested());
1312 ExternalLabel target_label(label_address); 1304 ExternalLabel target_label(label_address);
1313 __ LoadObject(R5, ic_data, PP); 1305 __ LoadObject(R5, ic_data, PP);
1314 GenerateDartCall(deopt_id, 1306 GenerateDartCall(deopt_id,
1315 token_pos, 1307 token_pos,
1316 &target_label, 1308 &target_label,
1317 RawPcDescriptors::kUnoptStaticCall, 1309 RawPcDescriptors::kUnoptStaticCall,
1318 locs); 1310 locs);
1319 __ Drop(argument_count); 1311 __ Drop(argument_count);
1320 } 1312 }
1321 1313
1322 1314
1323 void FlowGraphCompiler::EmitOptimizedStaticCall( 1315 void FlowGraphCompiler::EmitOptimizedStaticCall(
1324 const Function& function, 1316 const Function& function,
1325 const Array& arguments_descriptor, 1317 const Array& arguments_descriptor,
1326 intptr_t argument_count, 1318 intptr_t argument_count,
1327 intptr_t deopt_id, 1319 intptr_t deopt_id,
1328 intptr_t token_pos, 1320 intptr_t token_pos,
1329 LocationSummary* locs) { 1321 LocationSummary* locs) {
1330 StubCode* stub_code = isolate()->stub_code();
1331 __ LoadObject(R4, arguments_descriptor, PP); 1322 __ LoadObject(R4, arguments_descriptor, PP);
1332 // Do not use the code from the function, but let the code be patched so that 1323 // Do not use the code from the function, but let the code be patched so that
1333 // we can record the outgoing edges to other code. 1324 // we can record the outgoing edges to other code.
1334 GenerateDartCall(deopt_id, 1325 GenerateDartCall(deopt_id,
1335 token_pos, 1326 token_pos,
1336 &stub_code->CallStaticFunctionLabel(), 1327 &StubCode::CallStaticFunctionLabel(),
1337 RawPcDescriptors::kOther, 1328 RawPcDescriptors::kOther,
1338 locs); 1329 locs);
1339 AddStaticCallTarget(function); 1330 AddStaticCallTarget(function);
1340 __ Drop(argument_count); 1331 __ Drop(argument_count);
1341 } 1332 }
1342 1333
1343 1334
1344 Condition FlowGraphCompiler::EmitEqualityRegConstCompare( 1335 Condition FlowGraphCompiler::EmitEqualityRegConstCompare(
1345 Register reg, 1336 Register reg,
1346 const Object& obj, 1337 const Object& obj,
1347 bool needs_number_check, 1338 bool needs_number_check,
1348 intptr_t token_pos) { 1339 intptr_t token_pos) {
1349 if (needs_number_check) { 1340 if (needs_number_check) {
1350 StubCode* stub_code = isolate()->stub_code();
1351 ASSERT(!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint()); 1341 ASSERT(!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint());
1352 __ Push(reg); 1342 __ Push(reg);
1353 __ PushObject(obj, PP); 1343 __ PushObject(obj, PP);
1354 if (is_optimizing()) { 1344 if (is_optimizing()) {
1355 __ BranchLinkPatchable( 1345 __ BranchLinkPatchable(
1356 &stub_code->OptimizedIdenticalWithNumberCheckLabel()); 1346 &StubCode::OptimizedIdenticalWithNumberCheckLabel());
1357 } else { 1347 } else {
1358 __ BranchLinkPatchable( 1348 __ BranchLinkPatchable(
1359 &stub_code->UnoptimizedIdenticalWithNumberCheckLabel()); 1349 &StubCode::UnoptimizedIdenticalWithNumberCheckLabel());
1360 } 1350 }
1361 if (token_pos != Scanner::kNoSourcePos) { 1351 if (token_pos != Scanner::kNoSourcePos) {
1362 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, 1352 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
1363 Isolate::kNoDeoptId, 1353 Isolate::kNoDeoptId,
1364 token_pos); 1354 token_pos);
1365 } 1355 }
1366 // Stub returns result in flags (result of a cmp, we need Z computed). 1356 // Stub returns result in flags (result of a cmp, we need Z computed).
1367 __ Drop(1); // Discard constant. 1357 __ Drop(1); // Discard constant.
1368 __ Pop(reg); // Restore 'reg'. 1358 __ Pop(reg); // Restore 'reg'.
1369 } else { 1359 } else {
1370 __ CompareObject(reg, obj, PP); 1360 __ CompareObject(reg, obj, PP);
1371 } 1361 }
1372 return EQ; 1362 return EQ;
1373 } 1363 }
1374 1364
1375 1365
1376 Condition FlowGraphCompiler::EmitEqualityRegRegCompare(Register left, 1366 Condition FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
1377 Register right, 1367 Register right,
1378 bool needs_number_check, 1368 bool needs_number_check,
1379 intptr_t token_pos) { 1369 intptr_t token_pos) {
1380 if (needs_number_check) { 1370 if (needs_number_check) {
1381 StubCode* stub_code = isolate()->stub_code();
1382 __ Push(left); 1371 __ Push(left);
1383 __ Push(right); 1372 __ Push(right);
1384 if (is_optimizing()) { 1373 if (is_optimizing()) {
1385 __ BranchLinkPatchable( 1374 __ BranchLinkPatchable(
1386 &stub_code->OptimizedIdenticalWithNumberCheckLabel()); 1375 &StubCode::OptimizedIdenticalWithNumberCheckLabel());
1387 } else { 1376 } else {
1388 __ BranchLinkPatchable( 1377 __ BranchLinkPatchable(
1389 &stub_code->UnoptimizedIdenticalWithNumberCheckLabel()); 1378 &StubCode::UnoptimizedIdenticalWithNumberCheckLabel());
1390 } 1379 }
1391 if (token_pos != Scanner::kNoSourcePos) { 1380 if (token_pos != Scanner::kNoSourcePos) {
1392 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, 1381 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
1393 Isolate::kNoDeoptId, 1382 Isolate::kNoDeoptId,
1394 token_pos); 1383 token_pos);
1395 } 1384 }
1396 // Stub returns result in flags (result of a cmp, we need Z computed). 1385 // Stub returns result in flags (result of a cmp, we need Z computed).
1397 __ Pop(right); 1386 __ Pop(right);
1398 __ Pop(left); 1387 __ Pop(left);
1399 } else { 1388 } else {
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1482 Label* match_found, 1471 Label* match_found,
1483 intptr_t deopt_id, 1472 intptr_t deopt_id,
1484 intptr_t token_index, 1473 intptr_t token_index,
1485 LocationSummary* locs) { 1474 LocationSummary* locs) {
1486 ASSERT(is_optimizing()); 1475 ASSERT(is_optimizing());
1487 1476
1488 __ Comment("EmitTestAndCall"); 1477 __ Comment("EmitTestAndCall");
1489 const Array& arguments_descriptor = 1478 const Array& arguments_descriptor =
1490 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, 1479 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
1491 argument_names)); 1480 argument_names));
1492 StubCode* stub_code = isolate()->stub_code();
1493 1481
1494 // Load receiver into R0. 1482 // Load receiver into R0.
1495 __ LoadFromOffset(R0, SP, (argument_count - 1) * kWordSize, PP); 1483 __ LoadFromOffset(R0, SP, (argument_count - 1) * kWordSize, PP);
1496 __ LoadObject(R4, arguments_descriptor, PP); 1484 __ LoadObject(R4, arguments_descriptor, PP);
1497 1485
1498 const bool kFirstCheckIsSmi = ic_data.GetReceiverClassIdAt(0) == kSmiCid; 1486 const bool kFirstCheckIsSmi = ic_data.GetReceiverClassIdAt(0) == kSmiCid;
1499 const intptr_t kNumChecks = ic_data.NumberOfChecks(); 1487 const intptr_t kNumChecks = ic_data.NumberOfChecks();
1500 1488
1501 ASSERT(!ic_data.IsNull() && (kNumChecks > 0)); 1489 ASSERT(!ic_data.IsNull() && (kNumChecks > 0));
1502 1490
1503 Label after_smi_test; 1491 Label after_smi_test;
1504 __ tsti(R0, Immediate(kSmiTagMask)); 1492 __ tsti(R0, Immediate(kSmiTagMask));
1505 if (kFirstCheckIsSmi) { 1493 if (kFirstCheckIsSmi) {
1506 // Jump if receiver is not Smi. 1494 // Jump if receiver is not Smi.
1507 if (kNumChecks == 1) { 1495 if (kNumChecks == 1) {
1508 __ b(failed, NE); 1496 __ b(failed, NE);
1509 } else { 1497 } else {
1510 __ b(&after_smi_test, NE); 1498 __ b(&after_smi_test, NE);
1511 } 1499 }
1512 // Do not use the code from the function, but let the code be patched so 1500 // Do not use the code from the function, but let the code be patched so
1513 // that we can record the outgoing edges to other code. 1501 // that we can record the outgoing edges to other code.
1514 GenerateDartCall(deopt_id, 1502 GenerateDartCall(deopt_id,
1515 token_index, 1503 token_index,
1516 &stub_code->CallStaticFunctionLabel(), 1504 &StubCode::CallStaticFunctionLabel(),
1517 RawPcDescriptors::kOther, 1505 RawPcDescriptors::kOther,
1518 locs); 1506 locs);
1519 const Function& function = Function::Handle(ic_data.GetTargetAt(0)); 1507 const Function& function = Function::Handle(ic_data.GetTargetAt(0));
1520 AddStaticCallTarget(function); 1508 AddStaticCallTarget(function);
1521 __ Drop(argument_count); 1509 __ Drop(argument_count);
1522 if (kNumChecks > 1) { 1510 if (kNumChecks > 1) {
1523 __ b(match_found); 1511 __ b(match_found);
1524 } 1512 }
1525 } else { 1513 } else {
1526 // Receiver is Smi, but Smi is not a valid class therefore fail. 1514 // Receiver is Smi, but Smi is not a valid class therefore fail.
(...skipping 20 matching lines...) Expand all
1547 __ CompareImmediate(R2, sorted[i].cid, PP); 1535 __ CompareImmediate(R2, sorted[i].cid, PP);
1548 if (kIsLastCheck) { 1536 if (kIsLastCheck) {
1549 __ b(failed, NE); 1537 __ b(failed, NE);
1550 } else { 1538 } else {
1551 __ b(&next_test, NE); 1539 __ b(&next_test, NE);
1552 } 1540 }
1553 // Do not use the code from the function, but let the code be patched so 1541 // Do not use the code from the function, but let the code be patched so
1554 // that we can record the outgoing edges to other code. 1542 // that we can record the outgoing edges to other code.
1555 GenerateDartCall(deopt_id, 1543 GenerateDartCall(deopt_id,
1556 token_index, 1544 token_index,
1557 &stub_code->CallStaticFunctionLabel(), 1545 &StubCode::CallStaticFunctionLabel(),
1558 RawPcDescriptors::kOther, 1546 RawPcDescriptors::kOther,
1559 locs); 1547 locs);
1560 const Function& function = *sorted[i].target; 1548 const Function& function = *sorted[i].target;
1561 AddStaticCallTarget(function); 1549 AddStaticCallTarget(function);
1562 __ Drop(argument_count); 1550 __ Drop(argument_count);
1563 if (!kIsLastCheck) { 1551 if (!kIsLastCheck) {
1564 __ b(match_found); 1552 __ b(match_found);
1565 } 1553 }
1566 __ Bind(&next_test); 1554 __ Bind(&next_test);
1567 } 1555 }
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
1847 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { 1835 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) {
1848 __ PopDouble(reg); 1836 __ PopDouble(reg);
1849 } 1837 }
1850 1838
1851 1839
1852 #undef __ 1840 #undef __
1853 1841
1854 } // namespace dart 1842 } // namespace dart
1855 1843
1856 #endif // defined TARGET_ARCH_ARM64 1844 #endif // defined TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698