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

Side by Side Diff: src/x64/codegen-x64.cc

Issue 1858002: Port inlined version of swap primitive for sorting from ia32 to x64.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 7 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 | « src/x64/codegen-x64.h ('k') | src/x64/macro-assembler-x64.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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 4466 matching lines...) Expand 10 before | Expand all | Expand 10 after
4477 4477
4478 // Load the argument on the stack and jump to the runtime. 4478 // Load the argument on the stack and jump to the runtime.
4479 Load(args->at(0)); 4479 Load(args->at(0));
4480 4480
4481 NumberToStringStub stub; 4481 NumberToStringStub stub;
4482 Result result = frame_->CallStub(&stub, 1); 4482 Result result = frame_->CallStub(&stub, 1);
4483 frame_->Push(&result); 4483 frame_->Push(&result);
4484 } 4484 }
4485 4485
4486 4486
4487 class DeferredSwapElements: public DeferredCode {
4488 public:
4489 DeferredSwapElements(Register object, Register index1, Register index2)
4490 : object_(object), index1_(index1), index2_(index2) {
4491 set_comment("[ DeferredSwapElements");
4492 }
4493
4494 virtual void Generate();
4495
4496 private:
4497 Register object_, index1_, index2_;
4498 };
4499
4500
4501 void DeferredSwapElements::Generate() {
4502 __ push(object_);
4503 __ push(index1_);
4504 __ push(index2_);
4505 __ CallRuntime(Runtime::kSwapElements, 3);
4506 }
4507
4508
4487 void CodeGenerator::GenerateSwapElements(ZoneList<Expression*>* args) { 4509 void CodeGenerator::GenerateSwapElements(ZoneList<Expression*>* args) {
4488 Comment cmnt(masm_, "[ GenerateSwapElements"); 4510 Comment cmnt(masm_, "[ GenerateSwapElements");
4489 4511
4490 ASSERT_EQ(3, args->length()); 4512 ASSERT_EQ(3, args->length());
4491 4513
4492 Load(args->at(0)); 4514 Load(args->at(0));
4493 Load(args->at(1)); 4515 Load(args->at(1));
4494 Load(args->at(2)); 4516 Load(args->at(2));
4495 4517
4496 Result result = frame_->CallRuntime(Runtime::kSwapElements, 3); 4518 Result index2 = frame_->Pop();
4497 frame_->Push(&result); 4519 index2.ToRegister();
4520
4521 Result index1 = frame_->Pop();
4522 index1.ToRegister();
4523
4524 Result object = frame_->Pop();
4525 object.ToRegister();
4526
4527 Result tmp1 = allocator()->Allocate();
4528 tmp1.ToRegister();
4529 Result tmp2 = allocator()->Allocate();
4530 tmp2.ToRegister();
4531
4532 frame_->Spill(object.reg());
4533 frame_->Spill(index1.reg());
4534 frame_->Spill(index2.reg());
4535
4536 DeferredSwapElements* deferred = new DeferredSwapElements(object.reg(),
4537 index1.reg(),
4538 index2.reg());
4539
4540 // Fetch the map and check if array is in fast case.
4541 // Check that object doesn't require security checks and
4542 // has no indexed interceptor.
4543 __ CmpObjectType(object.reg(), FIRST_JS_OBJECT_TYPE, tmp1.reg());
4544 deferred->Branch(below);
4545 __ testb(FieldOperand(tmp1.reg(), Map::kBitFieldOffset),
4546 Immediate(KeyedLoadIC::kSlowCaseBitFieldMask));
4547 deferred->Branch(not_zero);
4548
4549 // Check the object's elements are in fast case.
4550 __ movq(tmp1.reg(), FieldOperand(object.reg(), JSObject::kElementsOffset));
4551 __ CompareRoot(FieldOperand(tmp1.reg(), HeapObject::kMapOffset),
4552 Heap::kFixedArrayMapRootIndex);
4553 deferred->Branch(not_equal);
4554
4555 // Check that both indices are smis.
4556 Condition both_smi = __ CheckBothSmi(index1.reg(), index2.reg());
4557 deferred->Branch(NegateCondition(both_smi));
4558
4559 // Bring addresses into index1 and index2.
4560 __ SmiToInteger32(index1.reg(), index1.reg());
4561 __ lea(index1.reg(), FieldOperand(tmp1.reg(),
4562 index1.reg(),
4563 times_pointer_size,
4564 FixedArray::kHeaderSize));
4565 __ SmiToInteger32(index2.reg(), index2.reg());
4566 __ lea(index2.reg(), FieldOperand(tmp1.reg(),
4567 index2.reg(),
4568 times_pointer_size,
4569 FixedArray::kHeaderSize));
4570
4571 // Swap elements.
4572 __ movq(object.reg(), Operand(index1.reg(), 0));
4573 __ movq(tmp2.reg(), Operand(index2.reg(), 0));
4574 __ movq(Operand(index2.reg(), 0), object.reg());
4575 __ movq(Operand(index1.reg(), 0), tmp2.reg());
4576
4577 Label done;
4578 __ InNewSpace(tmp1.reg(), tmp2.reg(), equal, &done);
4579 // Possible optimization: do a check that both values are Smis
4580 // (or them and test against Smi mask.)
4581
4582 __ movq(tmp2.reg(), tmp1.reg());
4583 RecordWriteStub recordWrite1(tmp2.reg(), index1.reg(), object.reg());
4584 __ CallStub(&recordWrite1);
4585
4586 RecordWriteStub recordWrite2(tmp1.reg(), index2.reg(), object.reg());
4587 __ CallStub(&recordWrite2);
4588
4589 __ bind(&done);
4590
4591 deferred->BindExit();
4592 frame_->Push(Factory::undefined_value());
4498 } 4593 }
4499 4594
4500 4595
4501 void CodeGenerator::GenerateCallFunction(ZoneList<Expression*>* args) { 4596 void CodeGenerator::GenerateCallFunction(ZoneList<Expression*>* args) {
4502 Comment cmnt(masm_, "[ GenerateCallFunction"); 4597 Comment cmnt(masm_, "[ GenerateCallFunction");
4503 4598
4504 ASSERT(args->length() >= 2); 4599 ASSERT(args->length() >= 2);
4505 4600
4506 int n_args = args->length() - 2; // for receiver and function. 4601 int n_args = args->length() - 2; // for receiver and function.
4507 Load(args->at(0)); // receiver 4602 Load(args->at(0)); // receiver
(...skipping 3621 matching lines...) Expand 10 before | Expand all | Expand 10 after
8129 // Generate code to lookup number in the number string cache. 8224 // Generate code to lookup number in the number string cache.
8130 GenerateLookupNumberStringCache(masm, rbx, rax, r8, r9, false, &runtime); 8225 GenerateLookupNumberStringCache(masm, rbx, rax, r8, r9, false, &runtime);
8131 __ ret(1 * kPointerSize); 8226 __ ret(1 * kPointerSize);
8132 8227
8133 __ bind(&runtime); 8228 __ bind(&runtime);
8134 // Handle number to string in the runtime system if not found in the cache. 8229 // Handle number to string in the runtime system if not found in the cache.
8135 __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1); 8230 __ TailCallRuntime(Runtime::kNumberToStringSkipCache, 1, 1);
8136 } 8231 }
8137 8232
8138 8233
8234 void RecordWriteStub::Generate(MacroAssembler* masm) {
8235 masm->RecordWriteHelper(object_, addr_, scratch_);
8236 masm->ret(0);
8237 }
8238
8239
8139 static int NegativeComparisonResult(Condition cc) { 8240 static int NegativeComparisonResult(Condition cc) {
8140 ASSERT(cc != equal); 8241 ASSERT(cc != equal);
8141 ASSERT((cc == less) || (cc == less_equal) 8242 ASSERT((cc == less) || (cc == less_equal)
8142 || (cc == greater) || (cc == greater_equal)); 8243 || (cc == greater) || (cc == greater_equal));
8143 return (cc == greater || cc == greater_equal) ? LESS : GREATER; 8244 return (cc == greater || cc == greater_equal) ? LESS : GREATER;
8144 } 8245 }
8145 8246
8146 void CompareStub::Generate(MacroAssembler* masm) { 8247 void CompareStub::Generate(MacroAssembler* masm) {
8147 Label call_builtin, done; 8248 Label call_builtin, done;
8148 // The compare stub returns a positive, negative, or zero 64-bit integer 8249 // The compare stub returns a positive, negative, or zero 64-bit integer
(...skipping 2882 matching lines...) Expand 10 before | Expand all | Expand 10 after
11031 // Call the function from C++. 11132 // Call the function from C++.
11032 return FUNCTION_CAST<ModuloFunction>(buffer); 11133 return FUNCTION_CAST<ModuloFunction>(buffer);
11033 } 11134 }
11034 11135
11035 #endif 11136 #endif
11036 11137
11037 11138
11038 #undef __ 11139 #undef __
11039 11140
11040 } } // namespace v8::internal 11141 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/codegen-x64.h ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698