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

Side by Side Diff: runtime/vm/flow_graph_compiler_x64.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) 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 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 Assembler* assem = compiler->assembler(); 182 Assembler* assem = compiler->assembler();
183 #define __ assem-> 183 #define __ assem->
184 __ Comment("%s", Name()); 184 __ Comment("%s", Name());
185 __ Bind(entry_label()); 185 __ Bind(entry_label());
186 if (FLAG_trap_on_deoptimization) { 186 if (FLAG_trap_on_deoptimization) {
187 __ int3(); 187 __ int3();
188 } 188 }
189 189
190 ASSERT(deopt_env() != NULL); 190 ASSERT(deopt_env() != NULL);
191 191
192 StubCode* stub_code = compiler->isolate()->stub_code(); 192 __ Call(&StubCode::DeoptimizeLabel(), PP);
193 __ Call(&stub_code->DeoptimizeLabel(), PP);
194 set_pc_offset(assem->CodeSize()); 193 set_pc_offset(assem->CodeSize());
195 __ int3(); 194 __ int3();
196 #undef __ 195 #undef __
197 } 196 }
198 197
199 198
200 #define __ assembler()-> 199 #define __ assembler()->
201 200
202 201
203 // Fall through if bool_register contains null. 202 // Fall through if bool_register contains null.
(...skipping 13 matching lines...) Expand all
217 // Clobbers RCX. 216 // Clobbers RCX.
218 RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub( 217 RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub(
219 TypeTestStubKind test_kind, 218 TypeTestStubKind test_kind,
220 Register instance_reg, 219 Register instance_reg,
221 Register type_arguments_reg, 220 Register type_arguments_reg,
222 Register temp_reg, 221 Register temp_reg,
223 Label* is_instance_lbl, 222 Label* is_instance_lbl,
224 Label* is_not_instance_lbl) { 223 Label* is_not_instance_lbl) {
225 const SubtypeTestCache& type_test_cache = 224 const SubtypeTestCache& type_test_cache =
226 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New()); 225 SubtypeTestCache::ZoneHandle(SubtypeTestCache::New());
227 StubCode* stub_code = isolate()->stub_code();
228 __ LoadUniqueObject(temp_reg, type_test_cache, PP); 226 __ LoadUniqueObject(temp_reg, type_test_cache, PP);
229 __ pushq(temp_reg); // Subtype test cache. 227 __ pushq(temp_reg); // Subtype test cache.
230 __ pushq(instance_reg); // Instance. 228 __ pushq(instance_reg); // Instance.
231 if (test_kind == kTestTypeOneArg) { 229 if (test_kind == kTestTypeOneArg) {
232 ASSERT(type_arguments_reg == kNoRegister); 230 ASSERT(type_arguments_reg == kNoRegister);
233 __ PushObject(Object::null_object(), PP); 231 __ PushObject(Object::null_object(), PP);
234 __ Call(&stub_code->Subtype1TestCacheLabel(), PP); 232 __ Call(&StubCode::Subtype1TestCacheLabel(), PP);
235 } else if (test_kind == kTestTypeTwoArgs) { 233 } else if (test_kind == kTestTypeTwoArgs) {
236 ASSERT(type_arguments_reg == kNoRegister); 234 ASSERT(type_arguments_reg == kNoRegister);
237 __ PushObject(Object::null_object(), PP); 235 __ PushObject(Object::null_object(), PP);
238 __ Call(&stub_code->Subtype2TestCacheLabel(), PP); 236 __ Call(&StubCode::Subtype2TestCacheLabel(), PP);
239 } else if (test_kind == kTestTypeThreeArgs) { 237 } else if (test_kind == kTestTypeThreeArgs) {
240 __ pushq(type_arguments_reg); 238 __ pushq(type_arguments_reg);
241 __ Call(&stub_code->Subtype3TestCacheLabel(), PP); 239 __ Call(&StubCode::Subtype3TestCacheLabel(), PP);
242 } else { 240 } else {
243 UNREACHABLE(); 241 UNREACHABLE();
244 } 242 }
245 // Result is in RCX: null -> not found, otherwise Bool::True or Bool::False. 243 // Result is in RCX: null -> not found, otherwise Bool::True or Bool::False.
246 ASSERT(instance_reg != RCX); 244 ASSERT(instance_reg != RCX);
247 ASSERT(temp_reg != RCX); 245 ASSERT(temp_reg != RCX);
248 __ popq(instance_reg); // Discard. 246 __ popq(instance_reg); // Discard.
249 __ popq(instance_reg); // Restore receiver. 247 __ popq(instance_reg); // Restore receiver.
250 __ popq(temp_reg); // Discard. 248 __ popq(temp_reg); // Discard.
251 GenerateBoolToJump(RCX, is_instance_lbl, is_not_instance_lbl); 249 GenerateBoolToJump(RCX, is_instance_lbl, is_not_instance_lbl);
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after
925 __ SmiUntag(RBX); 923 __ SmiUntag(RBX);
926 // Check that RCX equals RBX, i.e. no named arguments passed. 924 // Check that RCX equals RBX, i.e. no named arguments passed.
927 __ cmpq(RCX, RBX); 925 __ cmpq(RCX, RBX);
928 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump); 926 __ j(EQUAL, &all_arguments_processed, Assembler::kNearJump);
929 } 927 }
930 } 928 }
931 929
932 __ Bind(&wrong_num_arguments); 930 __ Bind(&wrong_num_arguments);
933 if (function.IsClosureFunction()) { 931 if (function.IsClosureFunction()) {
934 __ LeaveDartFrame(); // The arguments are still on the stack. 932 __ LeaveDartFrame(); // The arguments are still on the stack.
935 __ jmp(&isolate()->stub_code()->CallClosureNoSuchMethodLabel()); 933 __ jmp(&StubCode::CallClosureNoSuchMethodLabel());
936 // The noSuchMethod call may return to the caller, but not here. 934 // The noSuchMethod call may return to the caller, but not here.
937 } else if (check_correct_named_args) { 935 } else if (check_correct_named_args) {
938 __ Stop("Wrong arguments"); 936 __ Stop("Wrong arguments");
939 } 937 }
940 938
941 __ Bind(&all_arguments_processed); 939 __ Bind(&all_arguments_processed);
942 // Nullify originally passed arguments only after they have been copied and 940 // Nullify originally passed arguments only after they have been copied and
943 // checked, otherwise noSuchMethod would not see their original values. 941 // checked, otherwise noSuchMethod would not see their original values.
944 // This step can be skipped in case we decide that formal parameters are 942 // This step can be skipped in case we decide that formal parameters are
945 // implicitly final, since garbage collecting the unmodified value is not 943 // implicitly final, since garbage collecting the unmodified value is not
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1026 // Reoptimization of an optimized function is triggered by counting in 1024 // Reoptimization of an optimized function is triggered by counting in
1027 // IC stubs, but not at the entry of the function. 1025 // IC stubs, but not at the entry of the function.
1028 if (!is_optimizing()) { 1026 if (!is_optimizing()) {
1029 __ incl(FieldAddress(function_reg, Function::usage_counter_offset())); 1027 __ incl(FieldAddress(function_reg, Function::usage_counter_offset()));
1030 } 1028 }
1031 __ cmpl( 1029 __ cmpl(
1032 FieldAddress(function_reg, Function::usage_counter_offset()), 1030 FieldAddress(function_reg, Function::usage_counter_offset()),
1033 Immediate(GetOptimizationThreshold())); 1031 Immediate(GetOptimizationThreshold()));
1034 ASSERT(function_reg == RDI); 1032 ASSERT(function_reg == RDI);
1035 __ J(GREATER_EQUAL, 1033 __ J(GREATER_EQUAL,
1036 &isolate()->stub_code()->OptimizeFunctionLabel(), 1034 &StubCode::OptimizeFunctionLabel(),
1037 new_pp); 1035 new_pp);
1038 } else { 1036 } else {
1039 entry_patch_pc_offset_ = assembler()->CodeSize(); 1037 entry_patch_pc_offset_ = assembler()->CodeSize();
1040 } 1038 }
1041 ASSERT(StackSize() >= 0); 1039 ASSERT(StackSize() >= 0);
1042 __ Comment("Enter frame"); 1040 __ Comment("Enter frame");
1043 __ EnterDartFrameWithInfo(StackSize() * kWordSize, new_pp, new_pc); 1041 __ EnterDartFrameWithInfo(StackSize() * kWordSize, new_pp, new_pc);
1044 } 1042 }
1045 } 1043 }
1046 1044
1047 1045
1048 void FlowGraphCompiler::CompileGraph() { 1046 void FlowGraphCompiler::CompileGraph() {
1049 InitCompiler(); 1047 InitCompiler();
1050 1048
1051 TryIntrinsify(); 1049 TryIntrinsify();
1052 1050
1053 EmitFrameEntry(); 1051 EmitFrameEntry();
1054 1052
1055 const Function& function = parsed_function().function(); 1053 const Function& function = parsed_function().function();
1056 1054
1057 const int num_fixed_params = function.num_fixed_parameters(); 1055 const int num_fixed_params = function.num_fixed_parameters();
1058 const int num_copied_params = parsed_function().num_copied_params(); 1056 const int num_copied_params = parsed_function().num_copied_params();
1059 const int num_locals = parsed_function().num_stack_locals(); 1057 const int num_locals = parsed_function().num_stack_locals();
1060 StubCode* stub_code = isolate()->stub_code();
1061 1058
1062 // We check the number of passed arguments when we have to copy them due to 1059 // We check the number of passed arguments when we have to copy them due to
1063 // the presence of optional parameters. 1060 // the presence of optional parameters.
1064 // No such checking code is generated if only fixed parameters are declared, 1061 // No such checking code is generated if only fixed parameters are declared,
1065 // unless we are in debug mode or unless we are compiling a closure. 1062 // unless we are in debug mode or unless we are compiling a closure.
1066 if (num_copied_params == 0) { 1063 if (num_copied_params == 0) {
1067 #ifdef DEBUG 1064 #ifdef DEBUG
1068 ASSERT(!parsed_function().function().HasOptionalParameters()); 1065 ASSERT(!parsed_function().function().HasOptionalParameters());
1069 const bool check_arguments = !flow_graph().IsCompiledForOsr(); 1066 const bool check_arguments = !flow_graph().IsCompiledForOsr();
1070 #else 1067 #else
1071 const bool check_arguments = 1068 const bool check_arguments =
1072 function.IsClosureFunction() && !flow_graph().IsCompiledForOsr(); 1069 function.IsClosureFunction() && !flow_graph().IsCompiledForOsr();
1073 #endif 1070 #endif
1074 if (check_arguments) { 1071 if (check_arguments) {
1075 __ Comment("Check argument count"); 1072 __ Comment("Check argument count");
1076 // Check that exactly num_fixed arguments are passed in. 1073 // Check that exactly num_fixed arguments are passed in.
1077 Label correct_num_arguments, wrong_num_arguments; 1074 Label correct_num_arguments, wrong_num_arguments;
1078 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 1075 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
1079 __ CompareImmediate(RAX, Immediate(Smi::RawValue(num_fixed_params)), PP); 1076 __ CompareImmediate(RAX, Immediate(Smi::RawValue(num_fixed_params)), PP);
1080 __ j(NOT_EQUAL, &wrong_num_arguments, Assembler::kNearJump); 1077 __ j(NOT_EQUAL, &wrong_num_arguments, Assembler::kNearJump);
1081 __ cmpq(RAX, 1078 __ cmpq(RAX,
1082 FieldAddress(R10, 1079 FieldAddress(R10,
1083 ArgumentsDescriptor::positional_count_offset())); 1080 ArgumentsDescriptor::positional_count_offset()));
1084 __ j(EQUAL, &correct_num_arguments, Assembler::kNearJump); 1081 __ j(EQUAL, &correct_num_arguments, Assembler::kNearJump);
1085 1082
1086 __ Bind(&wrong_num_arguments); 1083 __ Bind(&wrong_num_arguments);
1087 if (function.IsClosureFunction()) { 1084 if (function.IsClosureFunction()) {
1088 __ LeaveDartFrame(); // The arguments are still on the stack. 1085 __ LeaveDartFrame(); // The arguments are still on the stack.
1089 __ jmp(&stub_code->CallClosureNoSuchMethodLabel()); 1086 __ jmp(&StubCode::CallClosureNoSuchMethodLabel());
1090 // The noSuchMethod call may return to the caller, but not here. 1087 // The noSuchMethod call may return to the caller, but not here.
1091 } else { 1088 } else {
1092 __ Stop("Wrong number of arguments"); 1089 __ Stop("Wrong number of arguments");
1093 } 1090 }
1094 __ Bind(&correct_num_arguments); 1091 __ Bind(&correct_num_arguments);
1095 } 1092 }
1096 } else if (!flow_graph().IsCompiledForOsr()) { 1093 } else if (!flow_graph().IsCompiledForOsr()) {
1097 CopyParameters(); 1094 CopyParameters();
1098 } 1095 }
1099 1096
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1145 ASSERT(!block_order().is_empty()); 1142 ASSERT(!block_order().is_empty());
1146 VisitBlocks(); 1143 VisitBlocks();
1147 1144
1148 __ int3(); 1145 __ int3();
1149 GenerateDeferredCode(); 1146 GenerateDeferredCode();
1150 // Emit function patching code. This will be swapped with the first 13 bytes 1147 // Emit function patching code. This will be swapped with the first 13 bytes
1151 // at entry point. 1148 // at entry point.
1152 patch_code_pc_offset_ = assembler()->CodeSize(); 1149 patch_code_pc_offset_ = assembler()->CodeSize();
1153 // This is patched up to a point in FrameEntry where the PP for the 1150 // This is patched up to a point in FrameEntry where the PP for the
1154 // current function is in R13 instead of PP. 1151 // current function is in R13 instead of PP.
1155 __ JmpPatchable(&stub_code->FixCallersTargetLabel(), R13); 1152 __ JmpPatchable(&StubCode::FixCallersTargetLabel(), R13);
1156 1153
1157 if (is_optimizing()) { 1154 if (is_optimizing()) {
1158 lazy_deopt_pc_offset_ = assembler()->CodeSize(); 1155 lazy_deopt_pc_offset_ = assembler()->CodeSize();
1159 __ Jmp(&stub_code->DeoptimizeLazyLabel(), PP); 1156 __ Jmp(&StubCode::DeoptimizeLazyLabel(), PP);
1160 } 1157 }
1161 } 1158 }
1162 1159
1163 1160
1164 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, 1161 void FlowGraphCompiler::GenerateCall(intptr_t token_pos,
1165 const ExternalLabel* label, 1162 const ExternalLabel* label,
1166 RawPcDescriptors::Kind kind, 1163 RawPcDescriptors::Kind kind,
1167 LocationSummary* locs) { 1164 LocationSummary* locs) {
1168 __ Call(label, PP); 1165 __ Call(label, PP);
1169 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos); 1166 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1214 } 1211 }
1215 } 1212 }
1216 1213
1217 1214
1218 void FlowGraphCompiler::EmitUnoptimizedStaticCall( 1215 void FlowGraphCompiler::EmitUnoptimizedStaticCall(
1219 intptr_t argument_count, 1216 intptr_t argument_count,
1220 intptr_t deopt_id, 1217 intptr_t deopt_id,
1221 intptr_t token_pos, 1218 intptr_t token_pos,
1222 LocationSummary* locs, 1219 LocationSummary* locs,
1223 const ICData& ic_data) { 1220 const ICData& ic_data) {
1224 StubCode* stub_code = isolate()->stub_code();
1225 const uword label_address = 1221 const uword label_address =
1226 stub_code->UnoptimizedStaticCallEntryPoint(ic_data.NumArgsTested()); 1222 StubCode::UnoptimizedStaticCallEntryPoint(ic_data.NumArgsTested());
1227 ExternalLabel target_label(label_address); 1223 ExternalLabel target_label(label_address);
1228 __ LoadObject(RBX, ic_data, PP); 1224 __ LoadObject(RBX, ic_data, PP);
1229 GenerateDartCall(deopt_id, 1225 GenerateDartCall(deopt_id,
1230 token_pos, 1226 token_pos,
1231 &target_label, 1227 &target_label,
1232 RawPcDescriptors::kUnoptStaticCall, 1228 RawPcDescriptors::kUnoptStaticCall,
1233 locs); 1229 locs);
1234 __ Drop(argument_count, RCX); 1230 __ Drop(argument_count, RCX);
1235 } 1231 }
1236 1232
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1318 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0)); 1314 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
1319 const MegamorphicCache& cache = 1315 const MegamorphicCache& cache =
1320 MegamorphicCache::ZoneHandle(table->Lookup(name, arguments_descriptor)); 1316 MegamorphicCache::ZoneHandle(table->Lookup(name, arguments_descriptor));
1321 const Register receiverR = RDI; 1317 const Register receiverR = RDI;
1322 const Register cacheR = RBX; 1318 const Register cacheR = RBX;
1323 const Register targetR = RCX; 1319 const Register targetR = RCX;
1324 __ movq(receiverR, Address(RSP, (argument_count - 1) * kWordSize)); 1320 __ movq(receiverR, Address(RSP, (argument_count - 1) * kWordSize));
1325 __ LoadObject(cacheR, cache, PP); 1321 __ LoadObject(cacheR, cache, PP);
1326 1322
1327 if (FLAG_use_megamorphic_stub) { 1323 if (FLAG_use_megamorphic_stub) {
1328 StubCode* stub_code = isolate()->stub_code(); 1324 __ call(&StubCode::MegamorphicLookupLabel());
1329 __ call(&stub_code->MegamorphicLookupLabel());
1330 } else { 1325 } else {
1331 StubCode::EmitMegamorphicLookup(assembler(), receiverR, cacheR, targetR); 1326 StubCode::EmitMegamorphicLookup(assembler(), receiverR, cacheR, targetR);
1332 } 1327 }
1333 __ LoadObject(RBX, ic_data, PP); 1328 __ LoadObject(RBX, ic_data, PP);
1334 __ LoadObject(R10, arguments_descriptor, PP); 1329 __ LoadObject(R10, arguments_descriptor, PP);
1335 __ call(targetR); 1330 __ call(targetR);
1336 AddCurrentDescriptor(RawPcDescriptors::kOther, 1331 AddCurrentDescriptor(RawPcDescriptors::kOther,
1337 Isolate::kNoDeoptId, token_pos); 1332 Isolate::kNoDeoptId, token_pos);
1338 RecordSafepoint(locs); 1333 RecordSafepoint(locs);
1339 const intptr_t deopt_id_after = Isolate::ToDeoptAfter(deopt_id); 1334 const intptr_t deopt_id_after = Isolate::ToDeoptAfter(deopt_id);
1340 if (is_optimizing()) { 1335 if (is_optimizing()) {
1341 AddDeoptIndexAtCall(deopt_id_after, token_pos); 1336 AddDeoptIndexAtCall(deopt_id_after, token_pos);
1342 } else { 1337 } else {
1343 // Add deoptimization continuation point after the call and before the 1338 // Add deoptimization continuation point after the call and before the
1344 // arguments are removed. 1339 // arguments are removed.
1345 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos); 1340 AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
1346 } 1341 }
1347 __ Drop(argument_count, RCX); 1342 __ Drop(argument_count, RCX);
1348 } 1343 }
1349 1344
1350 1345
1351 void FlowGraphCompiler::EmitOptimizedStaticCall( 1346 void FlowGraphCompiler::EmitOptimizedStaticCall(
1352 const Function& function, 1347 const Function& function,
1353 const Array& arguments_descriptor, 1348 const Array& arguments_descriptor,
1354 intptr_t argument_count, 1349 intptr_t argument_count,
1355 intptr_t deopt_id, 1350 intptr_t deopt_id,
1356 intptr_t token_pos, 1351 intptr_t token_pos,
1357 LocationSummary* locs) { 1352 LocationSummary* locs) {
1358 StubCode* stub_code = isolate()->stub_code();
1359 __ LoadObject(R10, arguments_descriptor, PP); 1353 __ LoadObject(R10, arguments_descriptor, PP);
1360 // Do not use the code from the function, but let the code be patched so that 1354 // Do not use the code from the function, but let the code be patched so that
1361 // we can record the outgoing edges to other code. 1355 // we can record the outgoing edges to other code.
1362 GenerateDartCall(deopt_id, 1356 GenerateDartCall(deopt_id,
1363 token_pos, 1357 token_pos,
1364 &stub_code->CallStaticFunctionLabel(), 1358 &StubCode::CallStaticFunctionLabel(),
1365 RawPcDescriptors::kOther, 1359 RawPcDescriptors::kOther,
1366 locs); 1360 locs);
1367 AddStaticCallTarget(function); 1361 AddStaticCallTarget(function);
1368 __ Drop(argument_count, RCX); 1362 __ Drop(argument_count, RCX);
1369 } 1363 }
1370 1364
1371 1365
1372 Condition FlowGraphCompiler::EmitEqualityRegConstCompare( 1366 Condition FlowGraphCompiler::EmitEqualityRegConstCompare(
1373 Register reg, 1367 Register reg,
1374 const Object& obj, 1368 const Object& obj,
1375 bool needs_number_check, 1369 bool needs_number_check,
1376 intptr_t token_pos) { 1370 intptr_t token_pos) {
1377 ASSERT(!needs_number_check || 1371 ASSERT(!needs_number_check ||
1378 (!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint())); 1372 (!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint()));
1379 1373
1380 if (obj.IsSmi() && (Smi::Cast(obj).Value() == 0)) { 1374 if (obj.IsSmi() && (Smi::Cast(obj).Value() == 0)) {
1381 ASSERT(!needs_number_check); 1375 ASSERT(!needs_number_check);
1382 __ testq(reg, reg); 1376 __ testq(reg, reg);
1383 return EQUAL; 1377 return EQUAL;
1384 } 1378 }
1385 1379
1386 if (needs_number_check) { 1380 if (needs_number_check) {
1387 StubCode* stub_code = isolate()->stub_code();
1388 __ pushq(reg); 1381 __ pushq(reg);
1389 __ PushObject(obj, PP); 1382 __ PushObject(obj, PP);
1390 if (is_optimizing()) { 1383 if (is_optimizing()) {
1391 __ CallPatchable(&stub_code->OptimizedIdenticalWithNumberCheckLabel()); 1384 __ CallPatchable(&StubCode::OptimizedIdenticalWithNumberCheckLabel());
1392 } else { 1385 } else {
1393 __ CallPatchable(&stub_code->UnoptimizedIdenticalWithNumberCheckLabel()); 1386 __ CallPatchable(&StubCode::UnoptimizedIdenticalWithNumberCheckLabel());
1394 } 1387 }
1395 if (token_pos != Scanner::kNoSourcePos) { 1388 if (token_pos != Scanner::kNoSourcePos) {
1396 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, 1389 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
1397 Isolate::kNoDeoptId, 1390 Isolate::kNoDeoptId,
1398 token_pos); 1391 token_pos);
1399 } 1392 }
1400 // Stub returns result in flags (result of a cmpq, we need ZF computed). 1393 // Stub returns result in flags (result of a cmpq, we need ZF computed).
1401 __ popq(reg); // Discard constant. 1394 __ popq(reg); // Discard constant.
1402 __ popq(reg); // Restore 'reg'. 1395 __ popq(reg); // Restore 'reg'.
1403 } else { 1396 } else {
1404 __ CompareObject(reg, obj, PP); 1397 __ CompareObject(reg, obj, PP);
1405 } 1398 }
1406 return EQUAL; 1399 return EQUAL;
1407 } 1400 }
1408 1401
1409 1402
1410 Condition FlowGraphCompiler::EmitEqualityRegRegCompare(Register left, 1403 Condition FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
1411 Register right, 1404 Register right,
1412 bool needs_number_check, 1405 bool needs_number_check,
1413 intptr_t token_pos) { 1406 intptr_t token_pos) {
1414 if (needs_number_check) { 1407 if (needs_number_check) {
1415 StubCode* stub_code = isolate()->stub_code();
1416 __ pushq(left); 1408 __ pushq(left);
1417 __ pushq(right); 1409 __ pushq(right);
1418 if (is_optimizing()) { 1410 if (is_optimizing()) {
1419 __ CallPatchable(&stub_code->OptimizedIdenticalWithNumberCheckLabel()); 1411 __ CallPatchable(&StubCode::OptimizedIdenticalWithNumberCheckLabel());
1420 } else { 1412 } else {
1421 __ CallPatchable(&stub_code->UnoptimizedIdenticalWithNumberCheckLabel()); 1413 __ CallPatchable(&StubCode::UnoptimizedIdenticalWithNumberCheckLabel());
1422 } 1414 }
1423 if (token_pos != Scanner::kNoSourcePos) { 1415 if (token_pos != Scanner::kNoSourcePos) {
1424 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, 1416 AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
1425 Isolate::kNoDeoptId, 1417 Isolate::kNoDeoptId,
1426 token_pos); 1418 token_pos);
1427 } 1419 }
1428 // Stub returns result in flags (result of a cmpq, we need ZF computed). 1420 // Stub returns result in flags (result of a cmpq, we need ZF computed).
1429 __ popq(right); 1421 __ popq(right);
1430 __ popq(left); 1422 __ popq(left);
1431 } else { 1423 } else {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1477 Label* match_found, 1469 Label* match_found,
1478 intptr_t deopt_id, 1470 intptr_t deopt_id,
1479 intptr_t token_index, 1471 intptr_t token_index,
1480 LocationSummary* locs) { 1472 LocationSummary* locs) {
1481 ASSERT(is_optimizing()); 1473 ASSERT(is_optimizing());
1482 1474
1483 __ Comment("EmitTestAndCall"); 1475 __ Comment("EmitTestAndCall");
1484 const Array& arguments_descriptor = 1476 const Array& arguments_descriptor =
1485 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, 1477 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
1486 argument_names)); 1478 argument_names));
1487 StubCode* stub_code = isolate()->stub_code();
1488 // Load receiver into RAX. 1479 // Load receiver into RAX.
1489 __ movq(RAX, 1480 __ movq(RAX,
1490 Address(RSP, (argument_count - 1) * kWordSize)); 1481 Address(RSP, (argument_count - 1) * kWordSize));
1491 __ LoadObject(R10, arguments_descriptor, PP); 1482 __ LoadObject(R10, arguments_descriptor, PP);
1492 1483
1493 const bool kFirstCheckIsSmi = ic_data.GetReceiverClassIdAt(0) == kSmiCid; 1484 const bool kFirstCheckIsSmi = ic_data.GetReceiverClassIdAt(0) == kSmiCid;
1494 const intptr_t kNumChecks = ic_data.NumberOfChecks(); 1485 const intptr_t kNumChecks = ic_data.NumberOfChecks();
1495 1486
1496 ASSERT(!ic_data.IsNull() && (kNumChecks > 0)); 1487 ASSERT(!ic_data.IsNull() && (kNumChecks > 0));
1497 1488
1498 Label after_smi_test; 1489 Label after_smi_test;
1499 __ testq(RAX, Immediate(kSmiTagMask)); 1490 __ testq(RAX, Immediate(kSmiTagMask));
1500 if (kFirstCheckIsSmi) { 1491 if (kFirstCheckIsSmi) {
1501 // Jump if receiver is not Smi. 1492 // Jump if receiver is not Smi.
1502 if (kNumChecks == 1) { 1493 if (kNumChecks == 1) {
1503 __ j(NOT_ZERO, failed); 1494 __ j(NOT_ZERO, failed);
1504 } else { 1495 } else {
1505 __ j(NOT_ZERO, &after_smi_test); 1496 __ j(NOT_ZERO, &after_smi_test);
1506 } 1497 }
1507 // Do not use the code from the function, but let the code be patched so 1498 // Do not use the code from the function, but let the code be patched so
1508 // that we can record the outgoing edges to other code. 1499 // that we can record the outgoing edges to other code.
1509 GenerateDartCall(deopt_id, 1500 GenerateDartCall(deopt_id,
1510 token_index, 1501 token_index,
1511 &stub_code->CallStaticFunctionLabel(), 1502 &StubCode::CallStaticFunctionLabel(),
1512 RawPcDescriptors::kOther, 1503 RawPcDescriptors::kOther,
1513 locs); 1504 locs);
1514 const Function& function = Function::Handle(ic_data.GetTargetAt(0)); 1505 const Function& function = Function::Handle(ic_data.GetTargetAt(0));
1515 AddStaticCallTarget(function); 1506 AddStaticCallTarget(function);
1516 __ Drop(argument_count, RCX); 1507 __ Drop(argument_count, RCX);
1517 if (kNumChecks > 1) { 1508 if (kNumChecks > 1) {
1518 __ jmp(match_found); 1509 __ jmp(match_found);
1519 } 1510 }
1520 } else { 1511 } else {
1521 // Receiver is Smi, but Smi is not a valid class therefore fail. 1512 // Receiver is Smi, but Smi is not a valid class therefore fail.
(...skipping 20 matching lines...) Expand all
1542 __ cmpl(RDI, Immediate(sorted[i].cid)); 1533 __ cmpl(RDI, Immediate(sorted[i].cid));
1543 if (kIsLastCheck) { 1534 if (kIsLastCheck) {
1544 __ j(NOT_EQUAL, failed); 1535 __ j(NOT_EQUAL, failed);
1545 } else { 1536 } else {
1546 __ j(NOT_EQUAL, &next_test); 1537 __ j(NOT_EQUAL, &next_test);
1547 } 1538 }
1548 // Do not use the code from the function, but let the code be patched so 1539 // Do not use the code from the function, but let the code be patched so
1549 // that we can record the outgoing edges to other code. 1540 // that we can record the outgoing edges to other code.
1550 GenerateDartCall(deopt_id, 1541 GenerateDartCall(deopt_id,
1551 token_index, 1542 token_index,
1552 &stub_code->CallStaticFunctionLabel(), 1543 &StubCode::CallStaticFunctionLabel(),
1553 RawPcDescriptors::kOther, 1544 RawPcDescriptors::kOther,
1554 locs); 1545 locs);
1555 const Function& function = *sorted[i].target; 1546 const Function& function = *sorted[i].target;
1556 AddStaticCallTarget(function); 1547 AddStaticCallTarget(function);
1557 __ Drop(argument_count, RCX); 1548 __ Drop(argument_count, RCX);
1558 if (!kIsLastCheck) { 1549 if (!kIsLastCheck) {
1559 __ jmp(match_found); 1550 __ jmp(match_found);
1560 } 1551 }
1561 __ Bind(&next_test); 1552 __ Bind(&next_test);
1562 } 1553 }
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
1794 __ movups(reg, Address(RSP, 0)); 1785 __ movups(reg, Address(RSP, 0));
1795 __ AddImmediate(RSP, Immediate(kFpuRegisterSize), PP); 1786 __ AddImmediate(RSP, Immediate(kFpuRegisterSize), PP);
1796 } 1787 }
1797 1788
1798 1789
1799 #undef __ 1790 #undef __
1800 1791
1801 } // namespace dart 1792 } // namespace dart
1802 1793
1803 #endif // defined TARGET_ARCH_X64 1794 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698