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

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

Issue 11956004: Fix vm code base so that it can be built for --arch=simarm (no snapshot yet). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 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.h ('k') | runtime/vm/flow_graph_compiler_arm.h » ('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) 2012, 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_XXX. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_XXX.
6 6
7 #include "vm/flow_graph_compiler.h" 7 #include "vm/flow_graph_compiler.h"
8 8
9 #include "vm/cha.h" 9 #include "vm/cha.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
11 #include "vm/debugger.h" 11 #include "vm/debugger.h"
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 GrowableObjectArray::New())), 150 GrowableObjectArray::New())),
151 is_optimizing_(is_optimizing), 151 is_optimizing_(is_optimizing),
152 may_reoptimize_(false), 152 may_reoptimize_(false),
153 double_class_(Class::ZoneHandle( 153 double_class_(Class::ZoneHandle(
154 Isolate::Current()->object_store()->double_class())), 154 Isolate::Current()->object_store()->double_class())),
155 parallel_move_resolver_(this) { 155 parallel_move_resolver_(this) {
156 ASSERT(assembler != NULL); 156 ASSERT(assembler != NULL);
157 } 157 }
158 158
159 159
160 FlowGraphCompiler::~FlowGraphCompiler() {
161 // BlockInfos are zone-allocated, so their destructors are not called.
162 // Verify the labels explicitly here.
163 for (int i = 0; i < block_info_.length(); ++i) {
164 ASSERT(!block_info_[i]->label.IsLinked());
165 ASSERT(!block_info_[i]->label.HasNear());
166 }
167 }
168
169
170 bool FlowGraphCompiler::HasFinally() const { 160 bool FlowGraphCompiler::HasFinally() const {
171 return parsed_function().function().has_finally(); 161 return parsed_function().function().has_finally();
172 } 162 }
173 163
174 164
175 void FlowGraphCompiler::InitCompiler() { 165 void FlowGraphCompiler::InitCompiler() {
176 pc_descriptors_list_ = new DescriptorList(64); 166 pc_descriptors_list_ = new DescriptorList(64);
177 exception_handlers_list_ = new ExceptionHandlerList(); 167 exception_handlers_list_ = new ExceptionHandlerList();
178 block_info_.Clear(); 168 block_info_.Clear();
179 for (int i = 0; i < block_order_.length(); ++i) { 169 for (int i = 0; i < block_order_.length(); ++i) {
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 ASSERT(bitmap->Length() <= StackSize()); 338 ASSERT(bitmap->Length() <= StackSize());
349 // Pad the bitmap out to describe all the spill slots. 339 // Pad the bitmap out to describe all the spill slots.
350 bitmap->SetLength(StackSize()); 340 bitmap->SetLength(StackSize());
351 341
352 // Mark the bits in the stack map in the same order we push registers in 342 // Mark the bits in the stack map in the same order we push registers in
353 // slow path code (see FlowGraphCompiler::SaveLiveRegisters). 343 // slow path code (see FlowGraphCompiler::SaveLiveRegisters).
354 // 344 //
355 // Slow path code can have registers at the safepoint. 345 // Slow path code can have registers at the safepoint.
356 if (!locs->always_calls()) { 346 if (!locs->always_calls()) {
357 RegisterSet* regs = locs->live_registers(); 347 RegisterSet* regs = locs->live_registers();
358 if (regs->xmm_regs_count() > 0) { 348 if (regs->fpu_regs_count() > 0) {
359 // Denote XMM registers with 0 bits in the stackmap. Based on the 349 // Denote FPU registers with 0 bits in the stackmap. Based on the
360 // assumption that there are normally few live XMM registers, this 350 // assumption that there are normally few live FPU registers, this
361 // encoding is simpler and roughly as compact as storing a separate 351 // encoding is simpler and roughly as compact as storing a separate
362 // count of XMM registers. 352 // count of FPU registers.
363 // 353 //
364 // XMM registers have the highest register number at the highest 354 // FPU registers have the highest register number at the highest
365 // address (i.e., first in the stackmap). 355 // address (i.e., first in the stackmap).
366 for (intptr_t i = kNumberOfXmmRegisters - 1; i >= 0; --i) { 356 for (intptr_t i = kNumberOfFpuRegisters - 1; i >= 0; --i) {
367 XmmRegister reg = static_cast<XmmRegister>(i); 357 FpuRegister reg = static_cast<FpuRegister>(i);
368 if (regs->ContainsXmmRegister(reg)) { 358 if (regs->ContainsFpuRegister(reg)) {
369 for (intptr_t j = 0; 359 for (intptr_t j = 0;
370 j < FlowGraphAllocator::kDoubleSpillSlotFactor; 360 j < FlowGraphAllocator::kDoubleSpillSlotFactor;
371 ++j) { 361 ++j) {
372 bitmap->Set(bitmap->Length(), false); 362 bitmap->Set(bitmap->Length(), false);
373 } 363 }
374 } 364 }
375 } 365 }
376 } 366 }
377 // General purpose registers have the lowest register number at the 367 // General purpose registers have the lowest register number at the
378 // highest address (i.e., first in the stackmap). 368 // highest address (i.e., first in the stackmap).
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 643
654 644
655 void FlowGraphCompiler::EmitComment(Instruction* instr) { 645 void FlowGraphCompiler::EmitComment(Instruction* instr) {
656 char buffer[256]; 646 char buffer[256];
657 BufferFormatter f(buffer, sizeof(buffer)); 647 BufferFormatter f(buffer, sizeof(buffer));
658 instr->PrintTo(&f); 648 instr->PrintTo(&f);
659 assembler()->Comment("%s", buffer); 649 assembler()->Comment("%s", buffer);
660 } 650 }
661 651
662 652
663 struct CidTarget {
664 intptr_t cid;
665 Function* target;
666 intptr_t count;
667 CidTarget(intptr_t cid_arg,
668 Function* target_arg,
669 intptr_t count_arg)
670 : cid(cid_arg), target(target_arg), count(count_arg) {}
671 };
672
673
674 // Returns 'sorted' array in decreasing count order.
675 // The expected number of elements to sort is less than 10.
676 static void SortICDataByCount(const ICData& ic_data,
677 GrowableArray<CidTarget>* sorted) {
678 ASSERT(ic_data.num_args_tested() == 1);
679 const intptr_t len = ic_data.NumberOfChecks();
680 sorted->Clear();
681
682 for (int i = 0; i < len; i++) {
683 sorted->Add(CidTarget(ic_data.GetReceiverClassIdAt(i),
684 &Function::ZoneHandle(ic_data.GetTargetAt(i)),
685 ic_data.GetCountAt(i)));
686 }
687 for (int i = 0; i < len; i++) {
688 intptr_t largest_ix = i;
689 for (int k = i + 1; k < len; k++) {
690 if ((*sorted)[largest_ix].count < (*sorted)[k].count) {
691 largest_ix = k;
692 }
693 }
694 if (i != largest_ix) {
695 // Swap.
696 CidTarget temp = (*sorted)[i];
697 (*sorted)[i] = (*sorted)[largest_ix];
698 (*sorted)[largest_ix] = temp;
699 }
700 }
701 }
702
703
704 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
705 Register class_id_reg,
706 intptr_t arg_count,
707 const Array& arg_names,
708 Label* deopt,
709 intptr_t deopt_id,
710 intptr_t token_index,
711 LocationSummary* locs) {
712 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
713 Label match_found;
714 const intptr_t len = ic_data.NumberOfChecks();
715 GrowableArray<CidTarget> sorted(len);
716 SortICDataByCount(ic_data, &sorted);
717 for (intptr_t i = 0; i < len; i++) {
718 const bool is_last_check = (i == (len - 1));
719 Label next_test;
720 assembler()->cmpl(class_id_reg, Immediate(sorted[i].cid));
721 if (is_last_check) {
722 assembler()->j(NOT_EQUAL, deopt);
723 } else {
724 assembler()->j(NOT_EQUAL, &next_test);
725 }
726 GenerateStaticCall(deopt_id,
727 token_index,
728 *sorted[i].target,
729 arg_count,
730 arg_names,
731 locs);
732 if (!is_last_check) {
733 assembler()->jmp(&match_found);
734 }
735 assembler()->Bind(&next_test);
736 }
737 assembler()->Bind(&match_found);
738 }
739
740
741 void FlowGraphCompiler::EmitDoubleCompareBranch(Condition true_condition,
742 XmmRegister left,
743 XmmRegister right,
744 BranchInstr* branch) {
745 ASSERT(branch != NULL);
746 assembler()->comisd(left, right);
747 BlockEntryInstr* nan_result = (true_condition == NOT_EQUAL) ?
748 branch->true_successor() : branch->false_successor();
749 assembler()->j(PARITY_EVEN, GetBlockLabel(nan_result));
750 branch->EmitBranchOnCondition(this, true_condition);
751 }
752
753
754
755 void FlowGraphCompiler::EmitDoubleCompareBool(Condition true_condition,
756 XmmRegister left,
757 XmmRegister right,
758 Register result) {
759 assembler()->comisd(left, right);
760 Label is_false, is_true, done;
761 assembler()->j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN false;
762 assembler()->j(true_condition, &is_true, Assembler::kNearJump);
763 assembler()->Bind(&is_false);
764 assembler()->LoadObject(result, Bool::False());
765 assembler()->jmp(&done);
766 assembler()->Bind(&is_true);
767 assembler()->LoadObject(result, Bool::True());
768 assembler()->Bind(&done);
769 }
770
771
772 // Allocate a register that is not explicitly blocked. 653 // Allocate a register that is not explicitly blocked.
773 static Register AllocateFreeRegister(bool* blocked_registers) { 654 static Register AllocateFreeRegister(bool* blocked_registers) {
774 for (intptr_t regno = 0; regno < kNumberOfCpuRegisters; regno++) { 655 for (intptr_t regno = 0; regno < kNumberOfCpuRegisters; regno++) {
775 if (!blocked_registers[regno]) { 656 if (!blocked_registers[regno]) {
776 blocked_registers[regno] = true; 657 blocked_registers[regno] = true;
777 return static_cast<Register>(regno); 658 return static_cast<Register>(regno);
778 } 659 }
779 } 660 }
780 UNREACHABLE(); 661 UNREACHABLE();
781 return kNoRegister; 662 return kNoRegister;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 case Location::kAny: 747 case Location::kAny:
867 case Location::kPrefersRegister: 748 case Location::kPrefersRegister:
868 case Location::kRequiresRegister: 749 case Location::kRequiresRegister:
869 case Location::kWritableRegister: 750 case Location::kWritableRegister:
870 result_location = Location::RegisterLocation( 751 result_location = Location::RegisterLocation(
871 AllocateFreeRegister(blocked_registers)); 752 AllocateFreeRegister(blocked_registers));
872 break; 753 break;
873 case Location::kSameAsFirstInput: 754 case Location::kSameAsFirstInput:
874 result_location = locs->in(0); 755 result_location = locs->in(0);
875 break; 756 break;
876 case Location::kRequiresXmmRegister: 757 case Location::kRequiresFpuRegister:
877 UNREACHABLE(); 758 UNREACHABLE();
878 break; 759 break;
879 } 760 }
880 locs->set_out(result_location); 761 locs->set_out(result_location);
881 } 762 }
882 } 763 }
883 764
884 765
885 ParallelMoveResolver::ParallelMoveResolver(FlowGraphCompiler* compiler) 766 ParallelMoveResolver::ParallelMoveResolver(FlowGraphCompiler* compiler)
886 : compiler_(compiler), moves_(32) {} 767 : compiler_(compiler), moves_(32) {}
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
983 EmitSwap(index); 864 EmitSwap(index);
984 return; 865 return;
985 } 866 }
986 } 867 }
987 868
988 // This move is not blocked. 869 // This move is not blocked.
989 EmitMove(index); 870 EmitMove(index);
990 } 871 }
991 872
992 873
993 Condition FlowGraphCompiler::FlipCondition(Condition condition) {
994 switch (condition) {
995 case EQUAL: return EQUAL;
996 case NOT_EQUAL: return NOT_EQUAL;
997 case LESS: return GREATER;
998 case LESS_EQUAL: return GREATER_EQUAL;
999 case GREATER: return LESS;
1000 case GREATER_EQUAL: return LESS_EQUAL;
1001 case BELOW: return ABOVE;
1002 case BELOW_EQUAL: return ABOVE_EQUAL;
1003 case ABOVE: return BELOW;
1004 case ABOVE_EQUAL: return BELOW_EQUAL;
1005 default:
1006 UNIMPLEMENTED();
1007 return EQUAL;
1008 }
1009 }
1010
1011
1012 bool FlowGraphCompiler::EvaluateCondition(Condition condition,
1013 intptr_t left,
1014 intptr_t right) {
1015 const uintptr_t unsigned_left = static_cast<uintptr_t>(left);
1016 const uintptr_t unsigned_right = static_cast<uintptr_t>(right);
1017 switch (condition) {
1018 case EQUAL: return left == right;
1019 case NOT_EQUAL: return left != right;
1020 case LESS: return left < right;
1021 case LESS_EQUAL: return left <= right;
1022 case GREATER: return left > right;
1023 case GREATER_EQUAL: return left >= right;
1024 case BELOW: return unsigned_left < unsigned_right;
1025 case BELOW_EQUAL: return unsigned_left <= unsigned_right;
1026 case ABOVE: return unsigned_left > unsigned_right;
1027 case ABOVE_EQUAL: return unsigned_left >= unsigned_right;
1028 default:
1029 UNIMPLEMENTED();
1030 return false;
1031 }
1032 }
1033
1034
1035 intptr_t FlowGraphCompiler::ElementSizeFor(intptr_t cid) { 874 intptr_t FlowGraphCompiler::ElementSizeFor(intptr_t cid) {
1036 switch (cid) { 875 switch (cid) {
1037 case kArrayCid: 876 case kArrayCid:
1038 case kImmutableArrayCid: 877 case kImmutableArrayCid:
1039 return Array::kBytesPerElement; 878 return Array::kBytesPerElement;
1040 case kFloat32ArrayCid: 879 case kFloat32ArrayCid:
1041 return Float32Array::kBytesPerElement; 880 return Float32Array::kBytesPerElement;
1042 case kFloat64ArrayCid: 881 case kFloat64ArrayCid:
1043 return Float64Array::kBytesPerElement; 882 return Float64Array::kBytesPerElement;
1044 case kInt8ArrayCid: 883 case kInt8ArrayCid:
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1087 return OneByteString::data_offset(); 926 return OneByteString::data_offset();
1088 case kTwoByteStringCid: 927 case kTwoByteStringCid:
1089 return TwoByteString::data_offset(); 928 return TwoByteString::data_offset();
1090 default: 929 default:
1091 UNIMPLEMENTED(); 930 UNIMPLEMENTED();
1092 return Array::data_offset(); 931 return Array::data_offset();
1093 } 932 }
1094 } 933 }
1095 934
1096 935
1097 FieldAddress FlowGraphCompiler::ElementAddressForIntIndex(intptr_t cid,
1098 Register array,
1099 intptr_t index) {
1100 const int64_t disp =
1101 static_cast<int64_t>(index) * ElementSizeFor(cid) + DataOffsetFor(cid);
1102 ASSERT(Utils::IsInt(32, disp));
1103 return FieldAddress(array, static_cast<int32_t>(disp));
1104 }
1105
1106
1107 FieldAddress FlowGraphCompiler::ElementAddressForRegIndex(intptr_t cid,
1108 Register array,
1109 Register index) {
1110 // Note that index is smi-tagged, (i.e, times 2) for all arrays with element
1111 // size > 1. For Uint8Array and OneByteString the index is expected to be
1112 // untagged before accessing.
1113 ASSERT(kSmiTagShift == 1);
1114 switch (cid) {
1115 case kArrayCid:
1116 case kImmutableArrayCid:
1117 return FieldAddress(
1118 array, index, TIMES_HALF_WORD_SIZE, Array::data_offset());
1119 case kFloat32ArrayCid:
1120 return FieldAddress(array, index, TIMES_2, Float32Array::data_offset());
1121 case kFloat64ArrayCid:
1122 return FieldAddress(array, index, TIMES_4, Float64Array::data_offset());
1123 case kInt8ArrayCid:
1124 return FieldAddress(array, index, TIMES_1, Int8Array::data_offset());
1125 case kUint8ArrayCid:
1126 return FieldAddress(array, index, TIMES_1, Uint8Array::data_offset());
1127 case kUint8ClampedArrayCid:
1128 return
1129 FieldAddress(array, index, TIMES_1, Uint8ClampedArray::data_offset());
1130 case kInt16ArrayCid:
1131 return FieldAddress(array, index, TIMES_1, Int16Array::data_offset());
1132 case kUint16ArrayCid:
1133 return FieldAddress(array, index, TIMES_1, Uint16Array::data_offset());
1134 case kOneByteStringCid:
1135 return FieldAddress(array, index, TIMES_1, OneByteString::data_offset());
1136 case kTwoByteStringCid:
1137 return FieldAddress(array, index, TIMES_1, TwoByteString::data_offset());
1138 default:
1139 UNIMPLEMENTED();
1140 return FieldAddress(SPREG, 0);
1141 }
1142 }
1143
1144
1145 Address FlowGraphCompiler::ExternalElementAddressForIntIndex(intptr_t cid,
1146 Register array,
1147 intptr_t index) {
1148 return Address(array, index * ElementSizeFor(cid));
1149 }
1150
1151
1152 Address FlowGraphCompiler::ExternalElementAddressForRegIndex(intptr_t cid,
1153 Register array,
1154 Register index) {
1155 switch (cid) {
1156 case kExternalUint8ArrayCid:
1157 return Address(array, index, TIMES_1, 0);
1158 default:
1159 UNIMPLEMENTED();
1160 return Address(SPREG, 0);
1161 }
1162 }
1163
1164
1165 // Returns true if checking against this type is a direct class id comparison. 936 // Returns true if checking against this type is a direct class id comparison.
1166 bool FlowGraphCompiler::TypeCheckAsClassEquality(const AbstractType& type) { 937 bool FlowGraphCompiler::TypeCheckAsClassEquality(const AbstractType& type) {
1167 ASSERT(type.IsFinalized() && !type.IsMalformed()); 938 ASSERT(type.IsFinalized() && !type.IsMalformed());
1168 // Requires CHA, which can be applied in optimized code only, 939 // Requires CHA, which can be applied in optimized code only,
1169 if (!FLAG_use_cha || !is_optimizing()) return false; 940 if (!FLAG_use_cha || !is_optimizing()) return false;
1170 if (!type.IsInstantiated()) return false; 941 if (!type.IsInstantiated()) return false;
1171 const Class& type_class = Class::Handle(type.type_class()); 942 const Class& type_class = Class::Handle(type.type_class());
1172 // Signature classes have different type checking rules. 943 // Signature classes have different type checking rules.
1173 if (type_class.IsSignatureClass()) return false; 944 if (type_class.IsSignatureClass()) return false;
1174 // Could be an interface check? 945 // Could be an interface check?
1175 if (type_class.is_implemented()) return false; 946 if (type_class.is_implemented()) return false;
1176 const intptr_t type_cid = type_class.id(); 947 const intptr_t type_cid = type_class.id();
1177 if (CHA::HasSubclasses(type_cid)) return false; 948 if (CHA::HasSubclasses(type_cid)) return false;
1178 if (type_class.HasTypeArguments()) { 949 if (type_class.HasTypeArguments()) {
1179 // Only raw types can be directly compared, thus disregarding type 950 // Only raw types can be directly compared, thus disregarding type
1180 // arguments. 951 // arguments.
1181 const AbstractTypeArguments& type_arguments = 952 const AbstractTypeArguments& type_arguments =
1182 AbstractTypeArguments::Handle(type.arguments()); 953 AbstractTypeArguments::Handle(type.arguments());
1183 const bool is_raw_type = type_arguments.IsNull() || 954 const bool is_raw_type = type_arguments.IsNull() ||
1184 type_arguments.IsRaw(type_arguments.Length()); 955 type_arguments.IsRaw(type_arguments.Length());
1185 return is_raw_type; 956 return is_raw_type;
1186 } 957 }
1187 return true; 958 return true;
1188 } 959 }
1189 960
961
962 // Returns 'sorted' array in decreasing count order.
963 // The expected number of elements to sort is less than 10.
964 void FlowGraphCompiler::SortICDataByCount(const ICData& ic_data,
965 GrowableArray<CidTarget>* sorted) {
966 ASSERT(ic_data.num_args_tested() == 1);
967 const intptr_t len = ic_data.NumberOfChecks();
968 sorted->Clear();
969
970 for (int i = 0; i < len; i++) {
971 sorted->Add(CidTarget(ic_data.GetReceiverClassIdAt(i),
972 &Function::ZoneHandle(ic_data.GetTargetAt(i)),
973 ic_data.GetCountAt(i)));
974 }
975 for (int i = 0; i < len; i++) {
976 intptr_t largest_ix = i;
977 for (int k = i + 1; k < len; k++) {
978 if ((*sorted)[largest_ix].count < (*sorted)[k].count) {
979 largest_ix = k;
980 }
981 }
982 if (i != largest_ix) {
983 // Swap.
984 CidTarget temp = (*sorted)[i];
985 (*sorted)[i] = (*sorted)[largest_ix];
986 (*sorted)[largest_ix] = temp;
987 }
988 }
989 }
990
1190 } // namespace dart 991 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler.h ('k') | runtime/vm/flow_graph_compiler_arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698