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

Side by Side Diff: src/x87/code-stubs-x87.cc

Issue 1311413007: X87: Reland Vector ICs: platform support for vector-based stores. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 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
« no previous file with comments | « src/ic/x87/stub-cache-x87.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_X87 5 #if V8_TARGET_ARCH_X87
6 6
7 #include "src/base/bits.h" 7 #include "src/base/bits.h"
8 #include "src/bootstrapper.h" 8 #include "src/bootstrapper.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 4277 matching lines...) Expand 10 before | Expand all | Expand 10 after
4288 void VectorStoreICStub::Generate(MacroAssembler* masm) { 4288 void VectorStoreICStub::Generate(MacroAssembler* masm) {
4289 GenerateImpl(masm, false); 4289 GenerateImpl(masm, false);
4290 } 4290 }
4291 4291
4292 4292
4293 void VectorStoreICStub::GenerateForTrampoline(MacroAssembler* masm) { 4293 void VectorStoreICStub::GenerateForTrampoline(MacroAssembler* masm) {
4294 GenerateImpl(masm, true); 4294 GenerateImpl(masm, true);
4295 } 4295 }
4296 4296
4297 4297
4298 // value is on the stack already.
4299 static void HandlePolymorphicStoreCase(MacroAssembler* masm, Register receiver,
4300 Register key, Register vector,
4301 Register slot, Register feedback,
4302 Label* miss) {
4303 // feedback initially contains the feedback array
4304 Label next, next_loop, prepare_next;
4305 Label load_smi_map, compare_map;
4306 Label start_polymorphic;
4307
4308 __ push(receiver);
4309 __ push(vector);
4310
4311 Register receiver_map = receiver;
4312 Register cached_map = vector;
4313
4314 // Receiver might not be a heap object.
4315 __ JumpIfSmi(receiver, &load_smi_map);
4316 __ mov(receiver_map, FieldOperand(receiver, 0));
4317 __ bind(&compare_map);
4318 __ mov(cached_map, FieldOperand(feedback, FixedArray::OffsetOfElementAt(0)));
4319
4320 // A named keyed store might have a 2 element array, all other cases can count
4321 // on an array with at least 2 {map, handler} pairs, so they can go right
4322 // into polymorphic array handling.
4323 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset));
4324 __ j(not_equal, &start_polymorphic);
4325
4326 // found, now call handler.
4327 Register handler = feedback;
4328 DCHECK(handler.is(VectorStoreICDescriptor::ValueRegister()));
4329 __ mov(handler, FieldOperand(feedback, FixedArray::OffsetOfElementAt(1)));
4330 __ pop(vector);
4331 __ pop(receiver);
4332 __ lea(handler, FieldOperand(handler, Code::kHeaderSize));
4333 __ xchg(handler, Operand(esp, 0));
4334 __ ret(0);
4335
4336 // Polymorphic, we have to loop from 2 to N
4337
4338 // TODO(mvstanton): I think there is a bug here, we are assuming the
4339 // array has more than one map/handler pair, but we call this function in the
4340 // keyed store with a string key case, where it might be just an array of two
4341 // elements.
4342
4343 __ bind(&start_polymorphic);
4344 __ push(key);
4345 Register counter = key;
4346 __ mov(counter, Immediate(Smi::FromInt(2)));
4347 __ bind(&next_loop);
4348 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size,
4349 FixedArray::kHeaderSize));
4350 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset));
4351 __ j(not_equal, &prepare_next);
4352 __ mov(handler, FieldOperand(feedback, counter, times_half_pointer_size,
4353 FixedArray::kHeaderSize + kPointerSize));
4354 __ pop(key);
4355 __ pop(vector);
4356 __ pop(receiver);
4357 __ lea(handler, FieldOperand(handler, Code::kHeaderSize));
4358 __ xchg(handler, Operand(esp, 0));
4359 __ ret(0);
4360
4361 __ bind(&prepare_next);
4362 __ add(counter, Immediate(Smi::FromInt(2)));
4363 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset));
4364 __ j(less, &next_loop);
4365
4366 // We exhausted our array of map handler pairs.
4367 __ pop(key);
4368 __ pop(vector);
4369 __ pop(receiver);
4370 __ jmp(miss);
4371
4372 __ bind(&load_smi_map);
4373 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex);
4374 __ jmp(&compare_map);
4375 }
4376
4377
4378 static void HandleMonomorphicStoreCase(MacroAssembler* masm, Register receiver,
4379 Register key, Register vector,
4380 Register slot, Register weak_cell,
4381 Label* miss) {
4382 // The store ic value is on the stack.
4383 DCHECK(weak_cell.is(VectorStoreICDescriptor::ValueRegister()));
4384
4385 // feedback initially contains the feedback array
4386 Label compare_smi_map;
4387
4388 // Move the weak map into the weak_cell register.
4389 Register ic_map = weak_cell;
4390 __ mov(ic_map, FieldOperand(weak_cell, WeakCell::kValueOffset));
4391
4392 // Receiver might not be a heap object.
4393 __ JumpIfSmi(receiver, &compare_smi_map);
4394 __ cmp(ic_map, FieldOperand(receiver, 0));
4395 __ j(not_equal, miss);
4396 __ mov(weak_cell, FieldOperand(vector, slot, times_half_pointer_size,
4397 FixedArray::kHeaderSize + kPointerSize));
4398 __ lea(weak_cell, FieldOperand(weak_cell, Code::kHeaderSize));
4399 // Put the store ic value back in it's register.
4400 __ xchg(weak_cell, Operand(esp, 0));
4401 // "return" to the handler.
4402 __ ret(0);
4403
4404 // In microbenchmarks, it made sense to unroll this code so that the call to
4405 // the handler is duplicated for a HeapObject receiver and a Smi receiver.
4406 __ bind(&compare_smi_map);
4407 __ CompareRoot(ic_map, Heap::kHeapNumberMapRootIndex);
4408 __ j(not_equal, miss);
4409 __ mov(weak_cell, FieldOperand(vector, slot, times_half_pointer_size,
4410 FixedArray::kHeaderSize + kPointerSize));
4411 __ lea(weak_cell, FieldOperand(weak_cell, Code::kHeaderSize));
4412 // Put the store ic value back in it's register.
4413 __ xchg(weak_cell, Operand(esp, 0));
4414 // "return" to the handler.
4415 __ ret(0);
4416 }
4417
4418
4298 void VectorStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { 4419 void VectorStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
4420 Register receiver = VectorStoreICDescriptor::ReceiverRegister(); // edx
4421 Register key = VectorStoreICDescriptor::NameRegister(); // ecx
4422 Register value = VectorStoreICDescriptor::ValueRegister(); // eax
4423 Register vector = VectorStoreICDescriptor::VectorRegister(); // ebx
4424 Register slot = VectorStoreICDescriptor::SlotRegister(); // edi
4299 Label miss; 4425 Label miss;
4300 4426
4301 // TODO(mvstanton): Implement. 4427 __ push(value);
4428
4429 Register scratch = value;
4430 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size,
4431 FixedArray::kHeaderSize));
4432
4433 // Is it a weak cell?
4434 Label try_array;
4435 Label not_array, smi_key, key_okay;
4436 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex);
4437 __ j(not_equal, &try_array);
4438 HandleMonomorphicStoreCase(masm, receiver, key, vector, slot, scratch, &miss);
4439
4440 // Is it a fixed array?
4441 __ bind(&try_array);
4442 __ CompareRoot(FieldOperand(scratch, 0), Heap::kFixedArrayMapRootIndex);
4443 __ j(not_equal, &not_array);
4444 HandlePolymorphicStoreCase(masm, receiver, key, vector, slot, scratch, &miss);
4445
4446 __ bind(&not_array);
4447 __ CompareRoot(scratch, Heap::kmegamorphic_symbolRootIndex);
4448 __ j(not_equal, &miss);
4449
4450 __ pop(value);
4451 __ push(slot);
4452 __ push(vector);
4453 Code::Flags code_flags = Code::RemoveTypeAndHolderFromFlags(
4454 Code::ComputeHandlerFlags(Code::STORE_IC));
4455 masm->isolate()->stub_cache()->GenerateProbe(masm, Code::STORE_IC, code_flags,
4456 receiver, key, slot, no_reg);
4457 __ pop(vector);
4458 __ pop(slot);
4459 Label no_pop_miss;
4460 __ jmp(&no_pop_miss);
4461
4302 __ bind(&miss); 4462 __ bind(&miss);
4463 __ pop(value);
4464 __ bind(&no_pop_miss);
4303 StoreIC::GenerateMiss(masm); 4465 StoreIC::GenerateMiss(masm);
4304 } 4466 }
4305 4467
4306 4468
4307 void VectorKeyedStoreICStub::Generate(MacroAssembler* masm) { 4469 void VectorKeyedStoreICStub::Generate(MacroAssembler* masm) {
4308 GenerateImpl(masm, false); 4470 GenerateImpl(masm, false);
4309 } 4471 }
4310 4472
4311 4473
4312 void VectorKeyedStoreICStub::GenerateForTrampoline(MacroAssembler* masm) { 4474 void VectorKeyedStoreICStub::GenerateForTrampoline(MacroAssembler* masm) {
4313 GenerateImpl(masm, true); 4475 GenerateImpl(masm, true);
4314 } 4476 }
4315 4477
4316 4478
4479 static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm,
4480 Register receiver, Register key,
4481 Register vector, Register slot,
4482 Register feedback, Label* miss) {
4483 // feedback initially contains the feedback array
4484 Label next, next_loop, prepare_next;
4485 Label load_smi_map, compare_map;
4486 Label transition_call;
4487 Label pop_and_miss;
4488
4489 __ push(receiver);
4490 __ push(vector);
4491
4492 Register receiver_map = receiver;
4493 Register cached_map = vector;
4494
4495 // Receiver might not be a heap object.
4496 __ JumpIfSmi(receiver, &load_smi_map);
4497 __ mov(receiver_map, FieldOperand(receiver, 0));
4498 __ bind(&compare_map);
4499
4500 // Polymorphic, we have to loop from 0 to N - 1
4501 __ push(key);
4502 // On the stack we have:
4503 // key (esp)
4504 // vector
4505 // receiver
4506 // value
4507 Register counter = key;
4508 __ mov(counter, Immediate(Smi::FromInt(0)));
4509 __ bind(&next_loop);
4510 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size,
4511 FixedArray::kHeaderSize));
4512 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset));
4513 __ j(not_equal, &prepare_next);
4514 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size,
4515 FixedArray::kHeaderSize + kPointerSize));
4516 __ CompareRoot(cached_map, Heap::kUndefinedValueRootIndex);
4517 __ j(not_equal, &transition_call);
4518 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size,
4519 FixedArray::kHeaderSize + 2 * kPointerSize));
4520 __ pop(key);
4521 __ pop(vector);
4522 __ pop(receiver);
4523 __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize));
4524 __ xchg(feedback, Operand(esp, 0));
4525 __ ret(0);
4526
4527 __ bind(&transition_call);
4528 // Oh holy hell this will be tough.
4529 // The map goes in vector register.
4530 __ mov(receiver, FieldOperand(cached_map, WeakCell::kValueOffset));
4531 // The weak cell may have been cleared.
4532 __ JumpIfSmi(receiver, &pop_and_miss);
4533 // slot goes on the stack, and holds return address.
4534 __ xchg(slot, Operand(esp, 4 * kPointerSize));
4535 // Get the handler in value.
4536 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size,
4537 FixedArray::kHeaderSize + 2 * kPointerSize));
4538 __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize));
4539 // Pop key into place.
4540 __ pop(key);
4541 // Put the return address on top of stack, vector goes in slot.
4542 __ xchg(slot, Operand(esp, 0));
4543 // put the map on the stack, receiver holds receiver.
4544 __ xchg(receiver, Operand(esp, 1 * kPointerSize));
4545 // put the vector on the stack, slot holds value.
4546 __ xchg(slot, Operand(esp, 2 * kPointerSize));
4547 // feedback (value) = value, slot = handler.
4548 __ xchg(feedback, slot);
4549 __ jmp(slot);
4550
4551 __ bind(&prepare_next);
4552 __ add(counter, Immediate(Smi::FromInt(3)));
4553 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset));
4554 __ j(less, &next_loop);
4555
4556 // We exhausted our array of map handler pairs.
4557 __ bind(&pop_and_miss);
4558 __ pop(key);
4559 __ pop(vector);
4560 __ pop(receiver);
4561 __ jmp(miss);
4562
4563 __ bind(&load_smi_map);
4564 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex);
4565 __ jmp(&compare_map);
4566 }
4567
4568
4317 void VectorKeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { 4569 void VectorKeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
4570 Register receiver = VectorStoreICDescriptor::ReceiverRegister(); // edx
4571 Register key = VectorStoreICDescriptor::NameRegister(); // ecx
4572 Register value = VectorStoreICDescriptor::ValueRegister(); // eax
4573 Register vector = VectorStoreICDescriptor::VectorRegister(); // ebx
4574 Register slot = VectorStoreICDescriptor::SlotRegister(); // edi
4318 Label miss; 4575 Label miss;
4319 4576
4320 // TODO(mvstanton): Implement. 4577 __ push(value);
4578
4579 Register scratch = value;
4580 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size,
4581 FixedArray::kHeaderSize));
4582
4583 // Is it a weak cell?
4584 Label try_array;
4585 Label not_array, smi_key, key_okay;
4586 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex);
4587 __ j(not_equal, &try_array);
4588 HandleMonomorphicStoreCase(masm, receiver, key, vector, slot, scratch, &miss);
4589
4590 // Is it a fixed array?
4591 __ bind(&try_array);
4592 __ CompareRoot(FieldOperand(scratch, 0), Heap::kFixedArrayMapRootIndex);
4593 __ j(not_equal, &not_array);
4594 HandlePolymorphicKeyedStoreCase(masm, receiver, key, vector, slot, scratch,
4595 &miss);
4596
4597 __ bind(&not_array);
4598 Label try_poly_name;
4599 __ CompareRoot(scratch, Heap::kmegamorphic_symbolRootIndex);
4600 __ j(not_equal, &try_poly_name);
4601
4602 __ pop(value);
4603
4604 Handle<Code> megamorphic_stub =
4605 KeyedStoreIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState());
4606 __ jmp(megamorphic_stub, RelocInfo::CODE_TARGET);
4607
4608 __ bind(&try_poly_name);
4609 // We might have a name in feedback, and a fixed array in the next slot.
4610 __ cmp(key, scratch);
4611 __ j(not_equal, &miss);
4612 // If the name comparison succeeded, we know we have a fixed array with
4613 // at least one map/handler pair.
4614 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size,
4615 FixedArray::kHeaderSize + kPointerSize));
4616 HandlePolymorphicStoreCase(masm, receiver, key, vector, slot, scratch, &miss);
4617
4321 __ bind(&miss); 4618 __ bind(&miss);
4619 __ pop(value);
4322 KeyedStoreIC::GenerateMiss(masm); 4620 KeyedStoreIC::GenerateMiss(masm);
4323 } 4621 }
4324 4622
4325 4623
4326 void CallICTrampolineStub::Generate(MacroAssembler* masm) { 4624 void CallICTrampolineStub::Generate(MacroAssembler* masm) {
4327 EmitLoadTypeFeedbackVector(masm, ebx); 4625 EmitLoadTypeFeedbackVector(masm, ebx);
4328 CallICStub stub(isolate(), state()); 4626 CallICStub stub(isolate(), state());
4329 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); 4627 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
4330 } 4628 }
4331 4629
(...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after
5252 Operand(ebp, 7 * kPointerSize), NULL); 5550 Operand(ebp, 7 * kPointerSize), NULL);
5253 } 5551 }
5254 5552
5255 5553
5256 #undef __ 5554 #undef __
5257 5555
5258 } // namespace internal 5556 } // namespace internal
5259 } // namespace v8 5557 } // namespace v8
5260 5558
5261 #endif // V8_TARGET_ARCH_X87 5559 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « src/ic/x87/stub-cache-x87.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698