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

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

Issue 593363003: Expands the use of Immediate and Operand wrappers. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
6 #if defined(TARGET_ARCH_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
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 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 188
189 #define __ assembler()-> 189 #define __ assembler()->
190 190
191 191
192 // Fall through if bool_register contains null. 192 // Fall through if bool_register contains null.
193 void FlowGraphCompiler::GenerateBoolToJump(Register bool_register, 193 void FlowGraphCompiler::GenerateBoolToJump(Register bool_register,
194 Label* is_true, 194 Label* is_true,
195 Label* is_false) { 195 Label* is_false) {
196 __ TraceSimMsg("BoolToJump"); 196 __ TraceSimMsg("BoolToJump");
197 Label fall_through; 197 Label fall_through;
198 __ BranchEqual(bool_register, reinterpret_cast<int32_t>(Object::null()), 198 __ BranchEqual(bool_register, Object::null_object(), &fall_through);
199 &fall_through);
200 __ BranchEqual(bool_register, Bool::True(), is_true); 199 __ BranchEqual(bool_register, Bool::True(), is_true);
201 __ b(is_false); 200 __ b(is_false);
202 __ Bind(&fall_through); 201 __ Bind(&fall_through);
203 } 202 }
204 203
205 204
206 // A0: instance (must be preserved). 205 // A0: instance (must be preserved).
207 // A1: instantiator type arguments (if used). 206 // A1: instantiator type arguments (if used).
208 RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub( 207 RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub(
209 TypeTestStubKind test_kind, 208 TypeTestStubKind test_kind,
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 const TypeArguments& type_arguments = 271 const TypeArguments& type_arguments =
273 TypeArguments::ZoneHandle(type.arguments()); 272 TypeArguments::ZoneHandle(type.arguments());
274 const bool is_raw_type = type_arguments.IsNull() || 273 const bool is_raw_type = type_arguments.IsNull() ||
275 type_arguments.IsRaw(from_index, num_type_params); 274 type_arguments.IsRaw(from_index, num_type_params);
276 // Signature class is an instantiated parameterized type. 275 // Signature class is an instantiated parameterized type.
277 if (!type_class.IsSignatureClass()) { 276 if (!type_class.IsSignatureClass()) {
278 if (is_raw_type) { 277 if (is_raw_type) {
279 const Register kClassIdReg = T0; 278 const Register kClassIdReg = T0;
280 // dynamic type argument, check only classes. 279 // dynamic type argument, check only classes.
281 __ LoadClassId(kClassIdReg, kInstanceReg); 280 __ LoadClassId(kClassIdReg, kInstanceReg);
282 __ BranchEqual(kClassIdReg, type_class.id(), is_instance_lbl); 281 __ BranchEqual(kClassIdReg, Immediate(type_class.id()), is_instance_lbl);
283 // List is a very common case. 282 // List is a very common case.
284 if (IsListClass(type_class)) { 283 if (IsListClass(type_class)) {
285 GenerateListTypeCheck(kClassIdReg, is_instance_lbl); 284 GenerateListTypeCheck(kClassIdReg, is_instance_lbl);
286 } 285 }
287 return GenerateSubtype1TestCacheLookup( 286 return GenerateSubtype1TestCacheLookup(
288 token_pos, type_class, is_instance_lbl, is_not_instance_lbl); 287 token_pos, type_class, is_instance_lbl, is_not_instance_lbl);
289 } 288 }
290 // If one type argument only, check if type argument is Object or dynamic. 289 // If one type argument only, check if type argument is Object or dynamic.
291 if (type_arguments.Length() == 1) { 290 if (type_arguments.Length() == 1) {
292 const AbstractType& tp_argument = AbstractType::ZoneHandle( 291 const AbstractType& tp_argument = AbstractType::ZoneHandle(
(...skipping 23 matching lines...) Expand all
316 is_not_instance_lbl); 315 is_not_instance_lbl);
317 } 316 }
318 317
319 318
320 void FlowGraphCompiler::CheckClassIds(Register class_id_reg, 319 void FlowGraphCompiler::CheckClassIds(Register class_id_reg,
321 const GrowableArray<intptr_t>& class_ids, 320 const GrowableArray<intptr_t>& class_ids,
322 Label* is_equal_lbl, 321 Label* is_equal_lbl,
323 Label* is_not_equal_lbl) { 322 Label* is_not_equal_lbl) {
324 __ TraceSimMsg("CheckClassIds"); 323 __ TraceSimMsg("CheckClassIds");
325 for (intptr_t i = 0; i < class_ids.length(); i++) { 324 for (intptr_t i = 0; i < class_ids.length(); i++) {
326 __ BranchEqual(class_id_reg, class_ids[i], is_equal_lbl); 325 __ BranchEqual(class_id_reg, Immediate(class_ids[i]), is_equal_lbl);
327 } 326 }
328 __ b(is_not_equal_lbl); 327 __ b(is_not_equal_lbl);
329 } 328 }
330 329
331 330
332 // Testing against an instantiated type with no arguments, without 331 // Testing against an instantiated type with no arguments, without
333 // SubtypeTestCache. 332 // SubtypeTestCache.
334 // A0: instance being type checked (preserved). 333 // A0: instance being type checked (preserved).
335 // Clobbers: T0, T1, T2 334 // Clobbers: T0, T1, T2
336 // Returns true if there is a fallthrough. 335 // Returns true if there is a fallthrough.
(...skipping 16 matching lines...) Expand all
353 type_class, 352 type_class,
354 TypeArguments::Handle(), 353 TypeArguments::Handle(),
355 NULL)) { 354 NULL)) {
356 __ beq(T0, ZR, is_instance_lbl); 355 __ beq(T0, ZR, is_instance_lbl);
357 } else { 356 } else {
358 __ beq(T0, ZR, is_not_instance_lbl); 357 __ beq(T0, ZR, is_not_instance_lbl);
359 } 358 }
360 // Compare if the classes are equal. 359 // Compare if the classes are equal.
361 const Register kClassIdReg = T0; 360 const Register kClassIdReg = T0;
362 __ LoadClassId(kClassIdReg, kInstanceReg); 361 __ LoadClassId(kClassIdReg, kInstanceReg);
363 __ BranchEqual(kClassIdReg, type_class.id(), is_instance_lbl); 362 __ BranchEqual(kClassIdReg, Immediate(type_class.id()), is_instance_lbl);
364 363
365 // See ClassFinalizer::ResolveSuperTypeAndInterfaces for list of restricted 364 // See ClassFinalizer::ResolveSuperTypeAndInterfaces for list of restricted
366 // interfaces. 365 // interfaces.
367 // Bool interface can be implemented only by core class Bool. 366 // Bool interface can be implemented only by core class Bool.
368 if (type.IsBoolType()) { 367 if (type.IsBoolType()) {
369 __ BranchEqual(kClassIdReg, kBoolCid, is_instance_lbl); 368 __ BranchEqual(kClassIdReg, Immediate(kBoolCid), is_instance_lbl);
370 __ b(is_not_instance_lbl); 369 __ b(is_not_instance_lbl);
371 return false; 370 return false;
372 } 371 }
373 if (type.IsFunctionType()) { 372 if (type.IsFunctionType()) {
374 // Check if instance is a closure. 373 // Check if instance is a closure.
375 __ LoadClassById(T1, kClassIdReg); 374 __ LoadClassById(T1, kClassIdReg);
376 __ lw(T1, FieldAddress(T1, Class::signature_function_offset())); 375 __ lw(T1, FieldAddress(T1, Class::signature_function_offset()));
377 __ BranchNotEqual(T1, reinterpret_cast<int32_t>(Object::null()), 376 __ BranchNotEqual(T1, Object::null_object(), is_instance_lbl);
378 is_instance_lbl);
379 } 377 }
380 // Custom checking for numbers (Smi, Mint, Bigint and Double). 378 // Custom checking for numbers (Smi, Mint, Bigint and Double).
381 // Note that instance is not Smi (checked above). 379 // Note that instance is not Smi (checked above).
382 if (type.IsSubtypeOf(Type::Handle(Type::Number()), NULL)) { 380 if (type.IsSubtypeOf(Type::Handle(Type::Number()), NULL)) {
383 GenerateNumberTypeCheck( 381 GenerateNumberTypeCheck(
384 kClassIdReg, type, is_instance_lbl, is_not_instance_lbl); 382 kClassIdReg, type, is_instance_lbl, is_not_instance_lbl);
385 return false; 383 return false;
386 } 384 }
387 if (type.IsStringType()) { 385 if (type.IsStringType()) {
388 GenerateStringTypeCheck(kClassIdReg, is_instance_lbl, is_not_instance_lbl); 386 GenerateStringTypeCheck(kClassIdReg, is_instance_lbl, is_not_instance_lbl);
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 // If type is instantiated and non-parameterized, we can inline code 578 // If type is instantiated and non-parameterized, we can inline code
581 // checking whether the tested instance is a Smi. 579 // checking whether the tested instance is a Smi.
582 if (type.IsInstantiated()) { 580 if (type.IsInstantiated()) {
583 // A null object is only an instance of Object and dynamic, which has 581 // A null object is only an instance of Object and dynamic, which has
584 // already been checked above (if the type is instantiated). So we can 582 // already been checked above (if the type is instantiated). So we can
585 // return false here if the instance is null (and if the type is 583 // return false here if the instance is null (and if the type is
586 // instantiated). 584 // instantiated).
587 // We can only inline this null check if the type is instantiated at compile 585 // We can only inline this null check if the type is instantiated at compile
588 // time, since an uninstantiated type at compile time could be Object or 586 // time, since an uninstantiated type at compile time could be Object or
589 // dynamic at run time. 587 // dynamic at run time.
590 __ BranchEqual(A0, reinterpret_cast<int32_t>(Object::null()), 588 __ BranchEqual(A0, Object::null_object(), &is_not_instance);
591 &is_not_instance);
592 } 589 }
593 590
594 // Generate inline instanceof test. 591 // Generate inline instanceof test.
595 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(); 592 SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle();
596 test_cache = GenerateInlineInstanceof(token_pos, type, 593 test_cache = GenerateInlineInstanceof(token_pos, type,
597 &is_instance, &is_not_instance); 594 &is_instance, &is_not_instance);
598 595
599 // test_cache is null if there is no fall-through. 596 // test_cache is null if there is no fall-through.
600 Label done; 597 Label done;
601 if (!test_cache.IsNull()) { 598 if (!test_cache.IsNull()) {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 // Assignable check is skipped in FlowGraphBuilder, not here. 662 // Assignable check is skipped in FlowGraphBuilder, not here.
666 ASSERT(dst_type.IsMalformedOrMalbounded() || 663 ASSERT(dst_type.IsMalformedOrMalbounded() ||
667 (!dst_type.IsDynamicType() && !dst_type.IsObjectType())); 664 (!dst_type.IsDynamicType() && !dst_type.IsObjectType()));
668 // Preserve instantiator and its type arguments. 665 // Preserve instantiator and its type arguments.
669 __ addiu(SP, SP, Immediate(-2 * kWordSize)); 666 __ addiu(SP, SP, Immediate(-2 * kWordSize));
670 __ sw(A2, Address(SP, 1 * kWordSize)); 667 __ sw(A2, Address(SP, 1 * kWordSize));
671 668
672 // A null object is always assignable and is returned as result. 669 // A null object is always assignable and is returned as result.
673 Label is_assignable, runtime_call; 670 Label is_assignable, runtime_call;
674 671
675 __ BranchEqual(A0, reinterpret_cast<int32_t>(Object::null()), &is_assignable); 672 __ BranchEqual(A0, Object::null_object(), &is_assignable);
676 __ delay_slot()->sw(A1, Address(SP, 0 * kWordSize)); 673 __ delay_slot()->sw(A1, Address(SP, 0 * kWordSize));
677 674
678 // Generate throw new TypeError() if the type is malformed or malbounded. 675 // Generate throw new TypeError() if the type is malformed or malbounded.
679 if (dst_type.IsMalformedOrMalbounded()) { 676 if (dst_type.IsMalformedOrMalbounded()) {
680 __ addiu(SP, SP, Immediate(-4 * kWordSize)); 677 __ addiu(SP, SP, Immediate(-4 * kWordSize));
681 __ LoadObject(TMP, Object::null_object()); 678 __ LoadObject(TMP, Object::null_object());
682 __ sw(TMP, Address(SP, 3 * kWordSize)); // Make room for the result. 679 __ sw(TMP, Address(SP, 3 * kWordSize)); // Make room for the result.
683 __ sw(A0, Address(SP, 2 * kWordSize)); // Push the source object. 680 __ sw(A0, Address(SP, 2 * kWordSize)); // Push the source object.
684 __ LoadObject(TMP, dst_name); 681 __ LoadObject(TMP, dst_name);
685 __ sw(TMP, Address(SP, 1 * kWordSize)); // Push the destination name. 682 __ sw(TMP, Address(SP, 1 * kWordSize)); // Push the destination name.
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 ASSERT(parsed_function().first_parameter_index() == kFirstLocalSlotFromFp); 761 ASSERT(parsed_function().first_parameter_index() == kFirstLocalSlotFromFp);
765 762
766 // Check that min_num_pos_args <= num_pos_args <= max_num_pos_args, 763 // Check that min_num_pos_args <= num_pos_args <= max_num_pos_args,
767 // where num_pos_args is the number of positional arguments passed in. 764 // where num_pos_args is the number of positional arguments passed in.
768 const int min_num_pos_args = num_fixed_params; 765 const int min_num_pos_args = num_fixed_params;
769 const int max_num_pos_args = num_fixed_params + num_opt_pos_params; 766 const int max_num_pos_args = num_fixed_params + num_opt_pos_params;
770 767
771 __ lw(T2, FieldAddress(S4, ArgumentsDescriptor::positional_count_offset())); 768 __ lw(T2, FieldAddress(S4, ArgumentsDescriptor::positional_count_offset()));
772 // Check that min_num_pos_args <= num_pos_args. 769 // Check that min_num_pos_args <= num_pos_args.
773 Label wrong_num_arguments; 770 Label wrong_num_arguments;
774 __ BranchSignedLess(T2, Smi::RawValue(min_num_pos_args), 771 __ BranchSignedLess(T2, Immediate(Smi::RawValue(min_num_pos_args)),
775 &wrong_num_arguments); 772 &wrong_num_arguments);
776 773
777 // Check that num_pos_args <= max_num_pos_args. 774 // Check that num_pos_args <= max_num_pos_args.
778 __ BranchSignedGreater(T2, Smi::RawValue(max_num_pos_args), 775 __ BranchSignedGreater(T2, Immediate(Smi::RawValue(max_num_pos_args)),
779 &wrong_num_arguments); 776 &wrong_num_arguments);
780 777
781 // Copy positional arguments. 778 // Copy positional arguments.
782 // Argument i passed at fp[kParamEndSlotFromFp + num_args - i] is copied 779 // Argument i passed at fp[kParamEndSlotFromFp + num_args - i] is copied
783 // to fp[kFirstLocalSlotFromFp - i]. 780 // to fp[kFirstLocalSlotFromFp - i].
784 781
785 __ lw(T1, FieldAddress(S4, ArgumentsDescriptor::count_offset())); 782 __ lw(T1, FieldAddress(S4, ArgumentsDescriptor::count_offset()));
786 // Since T1 and T2 are Smi, use sll 1 instead of sll 2. 783 // Since T1 and T2 are Smi, use sll 1 instead of sll 2.
787 // Let T1 point to the last passed positional argument, i.e. to 784 // Let T1 point to the last passed positional argument, i.e. to
788 // fp[kParamEndSlotFromFp + num_args - (num_pos_args - 1)]. 785 // fp[kParamEndSlotFromFp + num_args - (num_pos_args - 1)].
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
882 // to be copied to the context that is not yet allocated. 879 // to be copied to the context that is not yet allocated.
883 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos; 880 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos;
884 __ sw(T3, Address(FP, computed_param_pos * kWordSize)); 881 __ sw(T3, Address(FP, computed_param_pos * kWordSize));
885 } 882 }
886 delete[] opt_param; 883 delete[] opt_param;
887 delete[] opt_param_position; 884 delete[] opt_param_position;
888 if (check_correct_named_args) { 885 if (check_correct_named_args) {
889 // Check that T0 now points to the null terminator in the arguments 886 // Check that T0 now points to the null terminator in the arguments
890 // descriptor. 887 // descriptor.
891 __ lw(T3, Address(T0)); 888 __ lw(T3, Address(T0));
892 __ BranchEqual(T3, reinterpret_cast<int32_t>(Object::null()), 889 __ BranchEqual(T3, Object::null_object(), &all_arguments_processed);
893 &all_arguments_processed);
894 } 890 }
895 } else { 891 } else {
896 ASSERT(num_opt_pos_params > 0); 892 ASSERT(num_opt_pos_params > 0);
897 __ Comment("There are optional positional parameters"); 893 __ Comment("There are optional positional parameters");
898 __ lw(T2, 894 __ lw(T2,
899 FieldAddress(S4, ArgumentsDescriptor::positional_count_offset())); 895 FieldAddress(S4, ArgumentsDescriptor::positional_count_offset()));
900 __ SmiUntag(T2); 896 __ SmiUntag(T2);
901 for (int i = 0; i < num_opt_pos_params; i++) { 897 for (int i = 0; i < num_opt_pos_params; i++) {
902 Label next_parameter; 898 Label next_parameter;
903 // Handle this optional positional parameter only if k or fewer positional 899 // Handle this optional positional parameter only if k or fewer positional
904 // arguments have been passed, where k is param_pos, the position of this 900 // arguments have been passed, where k is param_pos, the position of this
905 // optional parameter in the formal parameter list. 901 // optional parameter in the formal parameter list.
906 const int param_pos = num_fixed_params + i; 902 const int param_pos = num_fixed_params + i;
907 __ BranchSignedGreater(T2, param_pos, &next_parameter); 903 __ BranchSignedGreater(T2, Immediate(param_pos), &next_parameter);
908 // Load T3 with default argument. 904 // Load T3 with default argument.
909 const Object& value = Object::ZoneHandle( 905 const Object& value = Object::ZoneHandle(
910 parsed_function().default_parameter_values().At(i)); 906 parsed_function().default_parameter_values().At(i));
911 __ LoadObject(T3, value); 907 __ LoadObject(T3, value);
912 // Assign T3 to fp[kFirstLocalSlotFromFp - param_pos]. 908 // Assign T3 to fp[kFirstLocalSlotFromFp - param_pos].
913 // We do not use the final allocation index of the variable here, i.e. 909 // We do not use the final allocation index of the variable here, i.e.
914 // scope->VariableAt(i)->index(), because captured variables still need 910 // scope->VariableAt(i)->index(), because captured variables still need
915 // to be copied to the context that is not yet allocated. 911 // to be copied to the context that is not yet allocated.
916 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos; 912 const intptr_t computed_param_pos = kFirstLocalSlotFromFp - param_pos;
917 __ sw(T3, Address(FP, computed_param_pos * kWordSize)); 913 __ sw(T3, Address(FP, computed_param_pos * kWordSize));
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 __ lw(T1, FieldAddress(function_reg, Function::usage_counter_offset())); 1011 __ lw(T1, FieldAddress(function_reg, Function::usage_counter_offset()));
1016 // Reoptimization of an optimized function is triggered by counting in 1012 // Reoptimization of an optimized function is triggered by counting in
1017 // IC stubs, but not at the entry of the function. 1013 // IC stubs, but not at the entry of the function.
1018 if (!is_optimizing()) { 1014 if (!is_optimizing()) {
1019 __ addiu(T1, T1, Immediate(1)); 1015 __ addiu(T1, T1, Immediate(1));
1020 __ sw(T1, FieldAddress(function_reg, Function::usage_counter_offset())); 1016 __ sw(T1, FieldAddress(function_reg, Function::usage_counter_offset()));
1021 } 1017 }
1022 1018
1023 // Skip Branch if T1 is less than the threshold. 1019 // Skip Branch if T1 is less than the threshold.
1024 Label dont_branch; 1020 Label dont_branch;
1025 __ BranchSignedLess(T1, GetOptimizationThreshold(), &dont_branch); 1021 __ BranchSignedLess(
1022 T1, Immediate(GetOptimizationThreshold()), &dont_branch);
1026 1023
1027 ASSERT(function_reg == T0); 1024 ASSERT(function_reg == T0);
1028 __ Branch(&stub_code->OptimizeFunctionLabel()); 1025 __ Branch(&stub_code->OptimizeFunctionLabel());
1029 1026
1030 __ Bind(&dont_branch); 1027 __ Bind(&dont_branch);
1031 1028
1032 } else if (!flow_graph().IsCompiledForOsr()) { 1029 } else if (!flow_graph().IsCompiledForOsr()) {
1033 entry_patch_pc_offset_ = assembler()->CodeSize(); 1030 entry_patch_pc_offset_ = assembler()->CodeSize();
1034 } 1031 }
1035 __ Comment("Enter frame"); 1032 __ Comment("Enter frame");
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1078 #else 1075 #else
1079 const bool check_arguments = 1076 const bool check_arguments =
1080 function.IsClosureFunction() && !flow_graph().IsCompiledForOsr(); 1077 function.IsClosureFunction() && !flow_graph().IsCompiledForOsr();
1081 #endif 1078 #endif
1082 if (check_arguments) { 1079 if (check_arguments) {
1083 __ TraceSimMsg("Check argument count"); 1080 __ TraceSimMsg("Check argument count");
1084 __ Comment("Check argument count"); 1081 __ Comment("Check argument count");
1085 // Check that exactly num_fixed arguments are passed in. 1082 // Check that exactly num_fixed arguments are passed in.
1086 Label correct_num_arguments, wrong_num_arguments; 1083 Label correct_num_arguments, wrong_num_arguments;
1087 __ lw(T0, FieldAddress(S4, ArgumentsDescriptor::count_offset())); 1084 __ lw(T0, FieldAddress(S4, ArgumentsDescriptor::count_offset()));
1088 __ BranchNotEqual(T0, Smi::RawValue(num_fixed_params), 1085 __ BranchNotEqual(T0, Immediate(Smi::RawValue(num_fixed_params)),
1089 &wrong_num_arguments); 1086 &wrong_num_arguments);
1090 1087
1091 __ lw(T1, FieldAddress(S4, 1088 __ lw(T1, FieldAddress(S4,
1092 ArgumentsDescriptor::positional_count_offset())); 1089 ArgumentsDescriptor::positional_count_offset()));
1093 __ beq(T0, T1, &correct_num_arguments); 1090 __ beq(T0, T1, &correct_num_arguments);
1094 __ Bind(&wrong_num_arguments); 1091 __ Bind(&wrong_num_arguments);
1095 if (function.IsClosureFunction()) { 1092 if (function.IsClosureFunction()) {
1096 __ LeaveDartFrame(); // The arguments are still on the stack. 1093 __ LeaveDartFrame(); // The arguments are still on the stack.
1097 __ Branch(&isolate()->stub_code()->CallClosureNoSuchMethodLabel()); 1094 __ Branch(&isolate()->stub_code()->CallClosureNoSuchMethodLabel());
1098 // The noSuchMethod call may return to the caller, but not here. 1095 // The noSuchMethod call may return to the caller, but not here.
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
1541 argument_names)); 1538 argument_names));
1542 StubCode* stub_code = isolate()->stub_code(); 1539 StubCode* stub_code = isolate()->stub_code();
1543 1540
1544 __ TraceSimMsg("EmitTestAndCall"); 1541 __ TraceSimMsg("EmitTestAndCall");
1545 __ Comment("EmitTestAndCall"); 1542 __ Comment("EmitTestAndCall");
1546 __ LoadObject(S4, arguments_descriptor); 1543 __ LoadObject(S4, arguments_descriptor);
1547 for (intptr_t i = 0; i < len; i++) { 1544 for (intptr_t i = 0; i < len; i++) {
1548 const bool is_last_check = (i == (len - 1)); 1545 const bool is_last_check = (i == (len - 1));
1549 Label next_test; 1546 Label next_test;
1550 if (is_last_check) { 1547 if (is_last_check) {
1551 __ BranchNotEqual(class_id_reg, sorted[i].cid, deopt); 1548 __ BranchNotEqual(class_id_reg, Immediate(sorted[i].cid), deopt);
1552 } else { 1549 } else {
1553 __ BranchNotEqual(class_id_reg, sorted[i].cid, &next_test); 1550 __ BranchNotEqual(class_id_reg, Immediate(sorted[i].cid), &next_test);
1554 } 1551 }
1555 // Do not use the code from the function, but let the code be patched so 1552 // Do not use the code from the function, but let the code be patched so
1556 // that we can record the outgoing edges to other code. 1553 // that we can record the outgoing edges to other code.
1557 GenerateDartCall(deopt_id, 1554 GenerateDartCall(deopt_id,
1558 token_index, 1555 token_index,
1559 &stub_code->CallStaticFunctionLabel(), 1556 &stub_code->CallStaticFunctionLabel(),
1560 RawPcDescriptors::kOptStaticCall, 1557 RawPcDescriptors::kOptStaticCall,
1561 locs); 1558 locs);
1562 const Function& function = *sorted[i].target; 1559 const Function& function = *sorted[i].target;
1563 AddStaticCallTarget(function); 1560 AddStaticCallTarget(function);
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
1799 __ AddImmediate(SP, kDoubleSize); 1796 __ AddImmediate(SP, kDoubleSize);
1800 } 1797 }
1801 1798
1802 1799
1803 #undef __ 1800 #undef __
1804 1801
1805 1802
1806 } // namespace dart 1803 } // namespace dart
1807 1804
1808 #endif // defined TARGET_ARCH_MIPS 1805 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698