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

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

Issue 988653003: Use platform specific stubs for vector-based Load/KeyedLoad. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: slot_count = FLAG_vector_ics ? 2 : 1. Created 5 years, 9 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
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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_IA32 7 #if V8_TARGET_ARCH_IA32
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
11 #include "src/code-stubs.h" 11 #include "src/code-stubs.h"
12 #include "src/codegen.h" 12 #include "src/codegen.h"
13 #include "src/ic/handler-compiler.h" 13 #include "src/ic/handler-compiler.h"
14 #include "src/ic/ic.h" 14 #include "src/ic/ic.h"
15 #include "src/ic/stub-cache.h"
15 #include "src/isolate.h" 16 #include "src/isolate.h"
16 #include "src/jsregexp.h" 17 #include "src/jsregexp.h"
17 #include "src/regexp-macro-assembler.h" 18 #include "src/regexp-macro-assembler.h"
18 #include "src/runtime/runtime.h" 19 #include "src/runtime/runtime.h"
19 20
20 namespace v8 { 21 namespace v8 {
21 namespace internal { 22 namespace internal {
22 23
23 24
24 static void InitializeArrayConstructorDescriptor( 25 static void InitializeArrayConstructorDescriptor(
(...skipping 4367 matching lines...) Expand 10 before | Expand all | Expand 10 after
4392 __ pop(ecx); 4393 __ pop(ecx);
4393 int additional_offset = 4394 int additional_offset =
4394 function_mode() == JS_FUNCTION_STUB_MODE ? kPointerSize : 0; 4395 function_mode() == JS_FUNCTION_STUB_MODE ? kPointerSize : 0;
4395 __ lea(esp, MemOperand(esp, ebx, times_pointer_size, additional_offset)); 4396 __ lea(esp, MemOperand(esp, ebx, times_pointer_size, additional_offset));
4396 __ jmp(ecx); // Return to IC Miss stub, continuation still on stack. 4397 __ jmp(ecx); // Return to IC Miss stub, continuation still on stack.
4397 } 4398 }
4398 4399
4399 4400
4400 void LoadICTrampolineStub::Generate(MacroAssembler* masm) { 4401 void LoadICTrampolineStub::Generate(MacroAssembler* masm) {
4401 EmitLoadTypeFeedbackVector(masm, VectorLoadICDescriptor::VectorRegister()); 4402 EmitLoadTypeFeedbackVector(masm, VectorLoadICDescriptor::VectorRegister());
4402 VectorLoadStub stub(isolate(), state()); 4403 VectorRawLoadStub stub(isolate(), state());
4403 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); 4404 stub.GenerateForTrampoline(masm);
4405 // __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
4404 } 4406 }
4405 4407
4406 4408
4407 void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) { 4409 void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
4408 EmitLoadTypeFeedbackVector(masm, VectorLoadICDescriptor::VectorRegister()); 4410 EmitLoadTypeFeedbackVector(masm, VectorLoadICDescriptor::VectorRegister());
4409 VectorKeyedLoadStub stub(isolate()); 4411 VectorRawKeyedLoadStub stub(isolate());
4410 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); 4412 stub.GenerateForTrampoline(masm);
4411 } 4413 // __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
4412 4414 }
4413 4415
4416
4417 static void HandleArrayCases(MacroAssembler* masm, Register receiver,
4418 Register key, Register vector, Register slot,
4419 Register feedback, Label* miss) {
4420 // feedback initially contains the feedback array
4421 Label next, next_loop, prepare_next;
4422 Label load_smi_map, compare_map;
4423
4424 __ push(receiver);
4425 __ push(vector);
4426
4427 Register receiver_map = receiver;
4428 Register array_map = vector;
4429
4430 // Receiver might not be a heap object.
4431 __ JumpIfSmi(receiver, &load_smi_map);
4432 __ mov(receiver_map, FieldOperand(receiver, 0));
4433 __ bind(&compare_map);
4434 __ mov(array_map, FieldOperand(feedback, FixedArray::OffsetOfElementAt(0)));
4435 __ cmp(receiver_map, FieldOperand(array_map, WeakCell::kValueOffset));
4436 __ j(not_equal, &next);
4437 // found, now call handler.
4438 __ mov(feedback, FieldOperand(feedback, FixedArray::OffsetOfElementAt(1)));
Toon Verwaest 2015/03/11 17:55:02 feedback -> handler? Maybe just do Register handle
mvstanton 2015/03/12 17:05:34 Done.
4439 __ pop(vector);
4440 __ pop(receiver);
4441 __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize));
4442 __ jmp(feedback);
4443
4444 __ bind(&next);
4445 __ cmp(FieldOperand(feedback, FixedArray::kLengthOffset),
4446 Immediate(Smi::FromInt(2)));
Toon Verwaest 2015/03/11 17:55:01 This isn't possible for named loads afaict.
mvstanton 2015/03/12 17:05:34 I addressed this with a boolean, is_polymorphic.
4447 Label start_polymorphic;
4448 __ j(not_equal, &start_polymorphic);
4449 __ pop(vector);
4450 __ pop(receiver);
4451 __ jmp(miss);
4452
4453 // Polymorphic, we have to loop from 2 to N
4454 __ bind(&start_polymorphic);
4455 __ push(key);
Toon Verwaest 2015/03/11 17:55:02 As discussed, you don't need the key for named loa
mvstanton 2015/03/12 17:05:34 Yeah, I don't want to load it from the array very
4456 Register counter = key;
4457 __ mov(counter, Immediate(Smi::FromInt(2)));
4458 __ bind(&next_loop);
4459 __ mov(array_map, FieldOperand(feedback, counter, times_half_pointer_size,
4460 FixedArray::kHeaderSize));
4461 __ cmp(receiver_map, FieldOperand(array_map, WeakCell::kValueOffset));
4462 __ j(not_equal, &prepare_next);
4463 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size,
4464 FixedArray::kHeaderSize + kPointerSize));
4465 __ pop(key);
4466 __ pop(vector);
4467 __ pop(receiver);
4468 __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize));
4469 __ jmp(feedback);
4470
4471 __ bind(&prepare_next);
4472 __ add(counter, Immediate(Smi::FromInt(2)));
4473 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset));
4474 __ j(less, &next_loop);
4475
4476 // We exhausted our array of map handler pairs.
4477 __ pop(key);
4478 __ pop(vector);
4479 __ pop(receiver);
4480 __ jmp(miss);
4481
4482 __ bind(&load_smi_map);
4483 __ mov(receiver_map, masm->isolate()->factory()->heap_number_map());
4484 __ jmp(&compare_map);
4485 }
4486
4487
4488 static void HandleMonomorphicCase(MacroAssembler* masm, Register receiver,
4489 Register key, Register vector, Register slot,
4490 Register weak_cell, Label* miss) {
4491 // feedback initially contains the feedback array
4492 Label compare_smi_map;
4493
4494 // Move the weak map into the weak_cell register.
4495 __ mov(weak_cell, FieldOperand(weak_cell, WeakCell::kValueOffset));
4496
4497 // Receiver might not be a heap object.
4498 __ JumpIfSmi(receiver, &compare_smi_map);
4499 __ cmp(weak_cell, FieldOperand(receiver, 0));
Toon Verwaest 2015/03/11 17:55:02 Register receiver_map = weak_cell;
mvstanton 2015/03/12 17:05:34 Good idea, but I called it ic_map to indicate it's
4500 __ j(not_equal, miss);
4501 __ mov(weak_cell, FieldOperand(vector, slot, times_half_pointer_size,
Toon Verwaest 2015/03/11 17:55:02 Register code_object = weak_cell;
mvstanton 2015/03/12 17:05:34 Cool, but I called it handler per your good sugges
4502 FixedArray::kHeaderSize + kPointerSize));
4503 __ lea(weak_cell, FieldOperand(weak_cell, Code::kHeaderSize));
4504 __ jmp(weak_cell);
4505
4506 // In microbenchmarks, it made sense to unroll this code so that the call to
4507 // the handler is duplicated for a HeapObject receiver and a Smi receiver.
4508 __ bind(&compare_smi_map);
4509 __ cmp(weak_cell, masm->isolate()->factory()->heap_number_map());
4510 __ j(not_equal, miss);
4511 __ mov(weak_cell, FieldOperand(vector, slot, times_half_pointer_size,
4512 FixedArray::kHeaderSize + kPointerSize));
4513 __ lea(weak_cell, FieldOperand(weak_cell, Code::kHeaderSize));
4514 __ jmp(weak_cell);
4515 }
4516
4517
4518 void VectorRawLoadStub::Generate(MacroAssembler* masm) {
4519 GenerateImpl(masm, false);
4520 }
4521
4522
4523 void VectorRawLoadStub::GenerateForTrampoline(MacroAssembler* masm) {
4524 GenerateImpl(masm, true);
4525 }
4526
4527
4528 void VectorRawLoadStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
4529 Register receiver = VectorLoadICDescriptor::ReceiverRegister(); // edx
4530 Register name = VectorLoadICDescriptor::NameRegister(); // ecx
4531 Register vector = VectorLoadICDescriptor::VectorRegister(); // ebx
4532 Register slot = VectorLoadICDescriptor::SlotRegister(); // eax
4533 Factory* factory = masm->isolate()->factory();
4534 Register scratch = edi;
4535 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size,
4536 FixedArray::kHeaderSize));
4537
4538 // Is it a weak cell?
4539 Label try_array;
4540 Label not_array, smi_key, key_okay, miss;
4541 __ cmp(FieldOperand(scratch, 0), factory->weak_cell_map());
4542 __ j(not_equal, &try_array);
4543 HandleMonomorphicCase(masm, receiver, name, vector, slot, scratch, &miss);
4544 __ int3(); // We shouldn't get here.
4545
4546 // Is it a fixed array?
4547 __ bind(&try_array);
4548 __ cmp(FieldOperand(scratch, 0), factory->fixed_array_map());
4549 __ j(not_equal, &not_array);
4550 HandleArrayCases(masm, receiver, name, vector, slot, scratch, &miss);
4551 __ int3(); // We shouldn't get here.
4552
4553 __ bind(&not_array);
4554 __ cmp(scratch, factory->megamorphic_symbol());
4555 __ j(not_equal, &miss);
4556 __ push(slot);
4557 __ push(vector);
4558 Code::Flags code_flags = Code::RemoveTypeAndHolderFromFlags(
4559 Code::ComputeHandlerFlags(Code::LOAD_IC));
4560 masm->isolate()->stub_cache()->GenerateProbe(
4561 masm, Code::LOAD_IC, code_flags, false, receiver, name, vector, scratch);
4562 __ pop(vector);
4563 __ pop(slot);
4564
4565 __ bind(&miss);
4566 LoadIC::GenerateMiss(masm);
4567 }
4568
4569
4570 void VectorRawKeyedLoadStub::Generate(MacroAssembler* masm) {
4571 GenerateImpl(masm, false);
4572 }
4573
4574
4575 void VectorRawKeyedLoadStub::GenerateForTrampoline(MacroAssembler* masm) {
4576 GenerateImpl(masm, true);
4577 }
4578
4579
4580 void VectorRawKeyedLoadStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
4581 Register receiver = VectorLoadICDescriptor::ReceiverRegister(); // edx
4582 Register key = VectorLoadICDescriptor::NameRegister(); // ecx
4583 Register vector = VectorLoadICDescriptor::VectorRegister(); // ebx
4584 Register slot = VectorLoadICDescriptor::SlotRegister(); // eax
4585 Factory* factory = masm->isolate()->factory();
4586 Register scratch = edi;
4587 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size,
4588 FixedArray::kHeaderSize));
4589 // Is it a weak cell?
4590 Label try_array;
4591 Label not_array, smi_key, key_okay, miss;
4592 __ cmp(FieldOperand(scratch, 0), factory->weak_cell_map());
4593 __ j(not_equal, &try_array);
4594 __ JumpIfNotSmi(key, &miss);
4595 HandleMonomorphicCase(masm, receiver, key, vector, slot, scratch, &miss);
4596 __ int3(); // We shouldn't get here.
4597
4598 __ bind(&try_array);
4599 // Is it a fixed array?
4600 __ cmp(FieldOperand(scratch, 0), factory->fixed_array_map());
4601 __ j(not_equal, &not_array);
4602 // We have a polymorphic element handler.
4603 __ JumpIfNotSmi(key, &miss);
4604
4605 Label polymorphic, try_poly_name;
4606 __ bind(&polymorphic);
4607 HandleArrayCases(masm, receiver, key, vector, slot, scratch, &miss);
4608 __ int3(); // We shouldn't get here.
4609
4610 __ bind(&not_array);
4611 // Is it generic?
4612 __ cmp(scratch, factory->megamorphic_symbol());
4613 __ j(not_equal, &try_poly_name);
4614 Handle<Code> megamorphic_stub =
4615 KeyedLoadIC::ChooseMegamorphicStub(masm->isolate());
4616 __ jmp(megamorphic_stub, RelocInfo::CODE_TARGET);
4617 __ int3(); // We shouldn't get here.
Toon Verwaest 2015/03/11 17:55:01 drop int3(), I presume we can trust __jmp to do th
mvstanton 2015/03/12 17:05:34 Done.
4618
4619 __ bind(&try_poly_name);
4620 // We might have a name in scratch, and a fixed array in the next slot.
4621 __ cmp(key, scratch);
4622 __ j(not_equal, &miss);
4623 // If the name comparison succeeded, we know we have a fixed array with
4624 // at least one map/handler pair.
4625 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size,
4626 FixedArray::kHeaderSize + kPointerSize));
4627 __ jmp(&polymorphic);
4628
4629 __ bind(&miss);
4630 KeyedLoadIC::GenerateMiss(masm);
4631 }
4632
4633
4414 void CallICTrampolineStub::Generate(MacroAssembler* masm) { 4634 void CallICTrampolineStub::Generate(MacroAssembler* masm) {
4415 EmitLoadTypeFeedbackVector(masm, ebx); 4635 EmitLoadTypeFeedbackVector(masm, ebx);
4416 CallICStub stub(isolate(), state()); 4636 CallICStub stub(isolate(), state());
4417 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); 4637 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
4418 } 4638 }
4419 4639
4420 4640
4421 void CallIC_ArrayTrampolineStub::Generate(MacroAssembler* masm) { 4641 void CallIC_ArrayTrampolineStub::Generate(MacroAssembler* masm) {
4422 EmitLoadTypeFeedbackVector(masm, ebx); 4642 EmitLoadTypeFeedbackVector(masm, ebx);
4423 CallIC_ArrayStub stub(isolate(), state()); 4643 CallIC_ArrayStub stub(isolate(), state());
(...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after
5187 ApiParameterOperand(2), kStackSpace, nullptr, 5407 ApiParameterOperand(2), kStackSpace, nullptr,
5188 Operand(ebp, 7 * kPointerSize), NULL); 5408 Operand(ebp, 7 * kPointerSize), NULL);
5189 } 5409 }
5190 5410
5191 5411
5192 #undef __ 5412 #undef __
5193 5413
5194 } } // namespace v8::internal 5414 } } // namespace v8::internal
5195 5415
5196 #endif // V8_TARGET_ARCH_IA32 5416 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698