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

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

Issue 539153002: Port and integrate the irregexp engine from V8 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Port remaining V8 regexp tests and fix exposed bugs. Created 6 years, 2 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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 1198 matching lines...) Expand 10 before | Expand all | Expand 10 after
1209 } 1209 }
1210 break; 1210 break;
1211 default: 1211 default:
1212 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); 1212 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
1213 __ movl(result, element_address); 1213 __ movl(result, element_address);
1214 break; 1214 break;
1215 } 1215 }
1216 } 1216 }
1217 1217
1218 1218
1219 CompileType LoadCodeUnitsInstr::ComputeType() const {
1220 switch (class_id()) {
1221 case kOneByteStringCid:
1222 case kExternalOneByteStringCid:
1223 return CompileType::FromCid(element_count() < 4 ? kSmiCid : kMintCid);
1224 case kTwoByteStringCid:
1225 case kExternalTwoByteStringCid:
1226 return CompileType::FromCid(element_count() < 2 ? kSmiCid : kMintCid);
1227 default:
1228 UNIMPLEMENTED();
1229 return CompileType::Dynamic();
1230 }
1231 }
1232
1233
1234 Representation LoadCodeUnitsInstr::representation() const {
1235 switch (class_id()) {
1236 case kOneByteStringCid:
1237 case kExternalOneByteStringCid:
1238 return element_count() < 4 ? kTagged : kUnboxedMint;
1239 case kTwoByteStringCid:
1240 case kExternalTwoByteStringCid:
1241 return element_count() < 2 ? kTagged : kUnboxedMint;
1242 default:
1243 UNIMPLEMENTED();
1244 return kTagged;
1245 }
1246 }
1247
1248
1249 LocationSummary* LoadCodeUnitsInstr::MakeLocationSummary(Isolate* isolate,
1250 bool opt) const {
1251 const intptr_t kNumInputs = 2;
1252 const intptr_t kNumTemps = 0;
1253 LocationSummary* locs = new(isolate) LocationSummary(
1254 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
1255 locs->set_in(0, Location::RequiresRegister());
1256 // The smi index is either untagged (element size == 1), or it is left smi
1257 // tagged (for all element sizes > 1).
1258 if (index_scale() == 1) {
1259 locs->set_in(1, CanBeImmediateIndex(index(), class_id())
1260 ? Location::Constant(index()->definition()->AsConstant())
1261 : Location::WritableRegister());
1262 } else {
1263 locs->set_in(1, CanBeImmediateIndex(index(), class_id())
1264 ? Location::Constant(index()->definition()->AsConstant())
1265 : Location::RequiresRegister());
1266 }
1267
1268 if (representation() == kUnboxedMint) {
1269 locs->set_out(0, Location::Pair(Location::RequiresRegister(),
1270 Location::RequiresRegister()));
1271 } else {
1272 ASSERT(representation() == kTagged);
1273 locs->set_out(0, Location::RequiresRegister());
1274 }
1275
1276 return locs;
1277 }
1278
1279
1280 void LoadCodeUnitsInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1281 const Register array = locs()->in(0).reg();
1282 const Location index = locs()->in(1);
1283
1284 Address element_address = index.IsRegister()
1285 ? Assembler::ElementAddressForRegIndex(
1286 IsExternal(), class_id(), index_scale(), array, index.reg())
1287 : Assembler::ElementAddressForIntIndex(
1288 IsExternal(), class_id(), index_scale(),
1289 array, Smi::Cast(index.constant()).Value());
1290
1291 if ((index_scale() == 1) && index.IsRegister()) {
1292 __ SmiUntag(index.reg());
1293 }
1294
1295 if (representation() == kUnboxedMint) {
1296 ASSERT(locs()->out(0).IsPairLocation());
1297 PairLocation* result_pair = locs()->out(0).AsPairLocation();
1298 Register result1 = result_pair->At(0).reg();
1299 Register result2 = result_pair->At(1).reg();
1300 switch (class_id()) {
1301 case kOneByteStringCid:
1302 case kExternalOneByteStringCid:
1303 ASSERT(element_count() == 4);
1304 __ movl(result1, element_address);
1305 __ xorl(result2, result2);
1306 break;
1307 case kTwoByteStringCid:
1308 case kExternalTwoByteStringCid:
1309 ASSERT(element_count() == 2);
1310 __ movl(result1, element_address);
1311 __ xorl(result2, result2);
1312 break;
1313 default:
1314 UNREACHABLE();
1315 }
1316 } else {
1317 ASSERT(representation() == kTagged);
1318 Register result = locs()->out(0).reg();
1319 switch (class_id()) {
1320 case kOneByteStringCid:
1321 case kExternalOneByteStringCid:
1322 switch (element_count()) {
1323 case 1: __ movzxb(result, element_address); break;
1324 case 2: __ movzxw(result, element_address); break;
1325 default: UNREACHABLE();
1326 }
1327 __ SmiTag(result);
1328 break;
1329 case kTwoByteStringCid:
1330 case kExternalTwoByteStringCid:
1331 switch (element_count()) {
1332 case 1: __ movzxw(result, element_address); break;
1333 default: UNREACHABLE();
1334 }
1335 __ SmiTag(result);
1336 break;
1337 default:
1338 UNREACHABLE();
1339 break;
1340 }
1341 }
1342 }
1343
1344
1219 Representation StoreIndexedInstr::RequiredInputRepresentation( 1345 Representation StoreIndexedInstr::RequiredInputRepresentation(
1220 intptr_t idx) const { 1346 intptr_t idx) const {
1221 // Array can be a Dart object or a pointer to external data. 1347 // Array can be a Dart object or a pointer to external data.
1222 if (idx == 0) return kNoRepresentation; // Flexible input representation. 1348 if (idx == 0) return kNoRepresentation; // Flexible input representation.
1223 if (idx == 1) return kTagged; // Index is a smi. 1349 if (idx == 1) return kTagged; // Index is a smi.
1224 ASSERT(idx == 2); 1350 ASSERT(idx == 2);
1225 switch (class_id_) { 1351 switch (class_id_) {
1226 case kArrayCid: 1352 case kArrayCid:
1227 case kOneByteStringCid: 1353 case kOneByteStringCid:
1228 case kTypedDataInt8ArrayCid: 1354 case kTypedDataInt8ArrayCid:
(...skipping 3442 matching lines...) Expand 10 before | Expand all | Expand 10 after
4671 __ movsd(Address(ESP, 0), locs()->in(0).fpu_reg()); 4797 __ movsd(Address(ESP, 0), locs()->in(0).fpu_reg());
4672 __ CallRuntime(TargetFunction(), InputCount()); 4798 __ CallRuntime(TargetFunction(), InputCount());
4673 __ fstpl(Address(ESP, 0)); 4799 __ fstpl(Address(ESP, 0));
4674 __ movsd(locs()->out(0).fpu_reg(), Address(ESP, 0)); 4800 __ movsd(locs()->out(0).fpu_reg(), Address(ESP, 0));
4675 // Restore ESP. 4801 // Restore ESP.
4676 __ movl(ESP, locs()->temp(0).reg()); 4802 __ movl(ESP, locs()->temp(0).reg());
4677 } 4803 }
4678 } 4804 }
4679 4805
4680 4806
4807 LocationSummary* CaseInsensitiveCompareUC16Instr::MakeLocationSummary(
4808 Isolate* isolate, bool opt) const {
4809 const intptr_t kNumTemps = 1;
4810 LocationSummary* summary = new(isolate) LocationSummary(
4811 isolate, InputCount(), kNumTemps, LocationSummary::kCall);
4812 summary->set_in(0, Location::RegisterLocation(EAX));
4813 summary->set_in(1, Location::RegisterLocation(ECX));
4814 summary->set_in(2, Location::RegisterLocation(EDX));
4815 summary->set_in(3, Location::RegisterLocation(EBX));
4816 // EDI is chosen because it is callee saved so we do not need to back it
4817 // up before calling into the runtime.
4818 summary->set_temp(0, Location::RegisterLocation(EDI));
Florian Schneider 2014/10/01 17:04:14 At calls, no need to specify temps: All registers
jgruber1 2014/10/03 18:59:52 Done.
4819 summary->set_out(0, Location::RegisterLocation(EAX));
4820 return summary;
4821 }
4822
4823
4824 void CaseInsensitiveCompareUC16Instr::EmitNativeCode(
4825 FlowGraphCompiler* compiler) {
4826
4827 // Save ESP.
4828 __ movl(locs()->temp(0).reg(), ESP);
4829 __ ReserveAlignedFrameSpace(kWordSize * TargetFunction().argument_count());
4830
4831 __ movl(Address(ESP, + 0 * kWordSize), locs()->in(0).reg());
4832 __ movl(Address(ESP, + 1 * kWordSize), locs()->in(1).reg());
4833 __ movl(Address(ESP, + 2 * kWordSize), locs()->in(2).reg());
4834 __ movl(Address(ESP, + 3 * kWordSize), locs()->in(3).reg());
4835
4836 // Call the function.
4837 __ CallRuntime(TargetFunction(), TargetFunction().argument_count());
4838
4839 // Restore ESP.
4840 __ movl(ESP, locs()->temp(0).reg());
4841 }
4842
4843
4681 LocationSummary* MathMinMaxInstr::MakeLocationSummary(Isolate* isolate, 4844 LocationSummary* MathMinMaxInstr::MakeLocationSummary(Isolate* isolate,
4682 bool opt) const { 4845 bool opt) const {
4683 if (result_cid() == kDoubleCid) { 4846 if (result_cid() == kDoubleCid) {
4684 const intptr_t kNumInputs = 2; 4847 const intptr_t kNumInputs = 2;
4685 const intptr_t kNumTemps = 1; 4848 const intptr_t kNumTemps = 1;
4686 LocationSummary* summary = new(isolate) LocationSummary( 4849 LocationSummary* summary = new(isolate) LocationSummary(
4687 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4850 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4688 summary->set_in(0, Location::RequiresFpuRegister()); 4851 summary->set_in(0, Location::RequiresFpuRegister());
4689 summary->set_in(1, Location::RequiresFpuRegister()); 4852 summary->set_in(1, Location::RequiresFpuRegister());
4690 // Reuse the left register so that code can be made shorter. 4853 // Reuse the left register so that code can be made shorter.
(...skipping 1790 matching lines...) Expand 10 before | Expand all | Expand 10 after
6481 } 6644 }
6482 6645
6483 6646
6484 void GraphEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6647 void GraphEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6485 if (!compiler->CanFallThroughTo(normal_entry())) { 6648 if (!compiler->CanFallThroughTo(normal_entry())) {
6486 __ jmp(compiler->GetJumpLabel(normal_entry())); 6649 __ jmp(compiler->GetJumpLabel(normal_entry()));
6487 } 6650 }
6488 } 6651 }
6489 6652
6490 6653
6654 void IndirectEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6655 __ Bind(compiler->GetJumpLabel(this));
6656 if (!compiler->is_optimizing()) {
6657 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt,
6658 deopt_id_,
6659 Scanner::kNoSourcePos);
6660 }
6661 if (HasParallelMove()) {
6662 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
6663 }
6664 }
6665
6666
6491 LocationSummary* GotoInstr::MakeLocationSummary(Isolate* isolate, 6667 LocationSummary* GotoInstr::MakeLocationSummary(Isolate* isolate,
6492 bool opt) const { 6668 bool opt) const {
6493 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kNoCall); 6669 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kNoCall);
6494 } 6670 }
6495 6671
6496 6672
6497 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6673 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6498 if (!compiler->is_optimizing()) { 6674 if (!compiler->is_optimizing()) {
6499 if (FLAG_emit_edge_counters) { 6675 if (FLAG_emit_edge_counters) {
6500 compiler->EmitEdgeCounter(); 6676 compiler->EmitEdgeCounter();
(...skipping 12 matching lines...) Expand all
6513 } 6689 }
6514 6690
6515 // We can fall through if the successor is the next block in the list. 6691 // We can fall through if the successor is the next block in the list.
6516 // Otherwise, we need a jump. 6692 // Otherwise, we need a jump.
6517 if (!compiler->CanFallThroughTo(successor())) { 6693 if (!compiler->CanFallThroughTo(successor())) {
6518 __ jmp(compiler->GetJumpLabel(successor())); 6694 __ jmp(compiler->GetJumpLabel(successor()));
6519 } 6695 }
6520 } 6696 }
6521 6697
6522 6698
6699 LocationSummary* IndirectGotoInstr::MakeLocationSummary(Isolate* isolate,
6700 bool opt) const {
6701 const intptr_t kNumInputs = 1;
6702 const intptr_t kNumTemps = 1;
6703
6704 LocationSummary* locs = new(isolate) LocationSummary(
6705 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6706
6707 locs->set_in(0, Location::RequiresRegister());
6708 locs->set_temp(0, Location::RequiresRegister());
6709
6710 return locs;
6711 }
6712
6713
6714 void IndirectGotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6715 Register sum_reg = locs()->temp_slot(0)->reg();
6716
6717 // Load from [current frame pointer] + kPcMarkerSlotFromFp.
6718 __ movl(sum_reg, Address(EBP, kPcMarkerSlotFromFp * kWordSize));
6719
6720 // Subtract the entrypoint offset.
6721 __ SubImmediate(sum_reg, Immediate(Assembler::EntryPointToPcMarkerOffset()));
Florian Schneider 2014/10/01 17:04:14 Maybe fold this into the add below using lea: __
Florian Schneider 2014/10/02 11:58:12 Even better: subtract the offset Assembler::EntryP
jgruber1 2014/10/03 18:59:52 Done.
jgruber1 2014/10/03 18:59:52 Acknowledged.
6722
6723 // Add the offset.
6724 Register offset_reg = locs()->in(0).reg();
6725 __ SmiUntag(offset_reg);
6726 __ addl(sum_reg, offset_reg);
6727
6728 // Jump to the absolute address.
6729 __ jmp(sum_reg);
6730 }
6731
6732
6523 LocationSummary* CurrentContextInstr::MakeLocationSummary(Isolate* isolate, 6733 LocationSummary* CurrentContextInstr::MakeLocationSummary(Isolate* isolate,
6524 bool opt) const { 6734 bool opt) const {
6525 return LocationSummary::Make(isolate, 6735 return LocationSummary::Make(isolate,
6526 0, 6736 0,
6527 Location::RequiresRegister(), 6737 Location::RequiresRegister(),
6528 LocationSummary::kNoCall); 6738 LocationSummary::kNoCall);
6529 } 6739 }
6530 6740
6531 6741
6532 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6742 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
6780 __ movl(EDX, Immediate(kInvalidObjectPointer)); 6990 __ movl(EDX, Immediate(kInvalidObjectPointer));
6781 __ movl(EDX, Immediate(kInvalidObjectPointer)); 6991 __ movl(EDX, Immediate(kInvalidObjectPointer));
6782 #endif 6992 #endif
6783 } 6993 }
6784 6994
6785 } // namespace dart 6995 } // namespace dart
6786 6996
6787 #undef __ 6997 #undef __
6788 6998
6789 #endif // defined TARGET_ARCH_IA32 6999 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698