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

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

Issue 1032163002: Vector-ICs - speed towards the monomorphic exit as quickly as possible. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Turn off flag. Created 5 years, 8 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/arm64/code-stubs-arm64.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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_X64 7 #if V8_TARGET_ARCH_X64
8 8
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 4333 matching lines...) Expand 10 before | Expand all | Expand 10 after
4344 4344
4345 void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) { 4345 void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
4346 EmitLoadTypeFeedbackVector(masm, VectorLoadICDescriptor::VectorRegister()); 4346 EmitLoadTypeFeedbackVector(masm, VectorLoadICDescriptor::VectorRegister());
4347 VectorRawKeyedLoadStub stub(isolate()); 4347 VectorRawKeyedLoadStub stub(isolate());
4348 stub.GenerateForTrampoline(masm); 4348 stub.GenerateForTrampoline(masm);
4349 } 4349 }
4350 4350
4351 4351
4352 static void HandleArrayCases(MacroAssembler* masm, Register receiver, 4352 static void HandleArrayCases(MacroAssembler* masm, Register receiver,
4353 Register key, Register vector, Register slot, 4353 Register key, Register vector, Register slot,
4354 Register feedback, Register scratch1, 4354 Register feedback, Register receiver_map,
4355 Register scratch2, Register scratch3, 4355 Register scratch1, Register scratch2,
4356 Register scratch4, bool is_polymorphic, 4356 Register scratch3, bool is_polymorphic,
4357 Label* miss) { 4357 Label* miss) {
4358 // feedback initially contains the feedback array 4358 // feedback initially contains the feedback array
4359 Label next_loop, prepare_next; 4359 Label next_loop, prepare_next;
4360 Label load_smi_map, compare_map;
4361 Label start_polymorphic; 4360 Label start_polymorphic;
4362 4361
4363 Register receiver_map = scratch1; 4362 Register counter = scratch1;
4364 Register counter = scratch2; 4363 Register length = scratch2;
4365 Register length = scratch3; 4364 Register cached_map = scratch3;
4366 Register cached_map = scratch4;
4367 4365
4368 // Receiver might not be a heap object.
4369 __ JumpIfSmi(receiver, &load_smi_map);
4370 __ movp(receiver_map, FieldOperand(receiver, 0));
4371 __ bind(&compare_map);
4372 __ movp(cached_map, FieldOperand(feedback, FixedArray::OffsetOfElementAt(0))); 4366 __ movp(cached_map, FieldOperand(feedback, FixedArray::OffsetOfElementAt(0)));
4373 __ cmpp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); 4367 __ cmpp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset));
4374 __ j(not_equal, &start_polymorphic); 4368 __ j(not_equal, &start_polymorphic);
4375 4369
4376 // found, now call handler. 4370 // found, now call handler.
4377 Register handler = feedback; 4371 Register handler = feedback;
4378 __ movp(handler, FieldOperand(feedback, FixedArray::OffsetOfElementAt(1))); 4372 __ movp(handler, FieldOperand(feedback, FixedArray::OffsetOfElementAt(1)));
4379 __ leap(handler, FieldOperand(handler, Code::kHeaderSize)); 4373 __ leap(handler, FieldOperand(handler, Code::kHeaderSize));
4380 __ jmp(handler); 4374 __ jmp(handler);
4381 4375
(...skipping 18 matching lines...) Expand all
4400 __ leap(handler, FieldOperand(handler, Code::kHeaderSize)); 4394 __ leap(handler, FieldOperand(handler, Code::kHeaderSize));
4401 __ jmp(handler); 4395 __ jmp(handler);
4402 4396
4403 __ bind(&prepare_next); 4397 __ bind(&prepare_next);
4404 __ addl(counter, Immediate(2)); 4398 __ addl(counter, Immediate(2));
4405 __ cmpl(counter, length); 4399 __ cmpl(counter, length);
4406 __ j(less, &next_loop); 4400 __ j(less, &next_loop);
4407 4401
4408 // We exhausted our array of map handler pairs. 4402 // We exhausted our array of map handler pairs.
4409 __ jmp(miss); 4403 __ jmp(miss);
4410
4411 __ bind(&load_smi_map);
4412 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex);
4413 __ jmp(&compare_map);
4414 } 4404 }
4415 4405
4416 4406
4417 static void HandleMonomorphicCase(MacroAssembler* masm, Register receiver, 4407 static void HandleMonomorphicCase(MacroAssembler* masm, Register receiver,
4418 Register key, Register vector, Register slot, 4408 Register receiver_map, Register feedback,
4419 Register weak_cell, Register integer_slot, 4409 Register vector, Register integer_slot,
4420 Label* miss) { 4410 Label* compare_map, Label* load_smi_map,
4421 // feedback initially contains the feedback array 4411 Label* try_array) {
4422 Label compare_smi_map; 4412 __ JumpIfSmi(receiver, load_smi_map);
4413 __ movp(receiver_map, FieldOperand(receiver, 0));
4423 4414
4424 // Move the weak map into the weak_cell register. 4415 __ bind(compare_map);
4425 Register ic_map = weak_cell; 4416 __ cmpp(receiver_map, FieldOperand(feedback, WeakCell::kValueOffset));
4426 __ movp(ic_map, FieldOperand(weak_cell, WeakCell::kValueOffset)); 4417 __ j(not_equal, try_array);
4427 4418 Register handler = feedback;
4428 // Receiver might not be a heap object.
4429 __ JumpIfSmi(receiver, &compare_smi_map);
4430 __ cmpp(ic_map, FieldOperand(receiver, 0));
4431 __ j(not_equal, miss);
4432 Register handler = weak_cell;
4433 __ movp(handler, FieldOperand(vector, integer_slot, times_pointer_size, 4419 __ movp(handler, FieldOperand(vector, integer_slot, times_pointer_size,
4434 FixedArray::kHeaderSize + kPointerSize)); 4420 FixedArray::kHeaderSize + kPointerSize));
4435 __ leap(handler, FieldOperand(handler, Code::kHeaderSize)); 4421 __ leap(handler, FieldOperand(handler, Code::kHeaderSize));
4436 __ jmp(handler);
4437
4438 // In microbenchmarks, it made sense to unroll this code so that the call to
4439 // the handler is duplicated for a HeapObject receiver and a Smi receiver.
4440 __ bind(&compare_smi_map);
4441 __ CompareRoot(ic_map, Heap::kHeapNumberMapRootIndex);
4442 __ j(not_equal, miss);
4443 __ movp(handler, FieldOperand(vector, integer_slot, times_pointer_size,
4444 FixedArray::kHeaderSize + kPointerSize));
4445 __ leap(handler, FieldOperand(handler, Code::kHeaderSize));
4446 __ jmp(handler); 4422 __ jmp(handler);
4447 } 4423 }
4448 4424
4449 4425
4450 void VectorRawLoadStub::Generate(MacroAssembler* masm) { 4426 void VectorRawLoadStub::Generate(MacroAssembler* masm) {
4451 GenerateImpl(masm, false); 4427 GenerateImpl(masm, false);
4452 } 4428 }
4453 4429
4454 4430
4455 void VectorRawLoadStub::GenerateForTrampoline(MacroAssembler* masm) { 4431 void VectorRawLoadStub::GenerateForTrampoline(MacroAssembler* masm) {
4456 GenerateImpl(masm, true); 4432 GenerateImpl(masm, true);
4457 } 4433 }
4458 4434
4459 4435
4460 void VectorRawLoadStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { 4436 void VectorRawLoadStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
4461 Register receiver = VectorLoadICDescriptor::ReceiverRegister(); // rdx 4437 Register receiver = VectorLoadICDescriptor::ReceiverRegister(); // rdx
4462 Register name = VectorLoadICDescriptor::NameRegister(); // rcx 4438 Register name = VectorLoadICDescriptor::NameRegister(); // rcx
4463 Register vector = VectorLoadICDescriptor::VectorRegister(); // rbx 4439 Register vector = VectorLoadICDescriptor::VectorRegister(); // rbx
4464 Register slot = VectorLoadICDescriptor::SlotRegister(); // rax 4440 Register slot = VectorLoadICDescriptor::SlotRegister(); // rax
4465 Register feedback = rdi; 4441 Register feedback = rdi;
4466 Register integer_slot = r8; 4442 Register integer_slot = r8;
4443 Register receiver_map = r9;
4467 4444
4468 __ SmiToInteger32(integer_slot, slot); 4445 __ SmiToInteger32(integer_slot, slot);
4469 __ movp(feedback, FieldOperand(vector, integer_slot, times_pointer_size, 4446 __ movp(feedback, FieldOperand(vector, integer_slot, times_pointer_size,
4470 FixedArray::kHeaderSize)); 4447 FixedArray::kHeaderSize));
4471 4448
4472 // Is it a weak cell? 4449 // Try to quickly handle the monomorphic case without knowing for sure
4473 Label try_array; 4450 // if we have a weak cell in feedback. We do know it's safe to look
4474 Label not_array, smi_key, key_okay, miss; 4451 // at WeakCell::kValueOffset.
4475 __ CompareRoot(FieldOperand(feedback, 0), Heap::kWeakCellMapRootIndex); 4452 Label try_array, load_smi_map, compare_map;
4476 __ j(not_equal, &try_array); 4453 Label not_array, miss;
4477 HandleMonomorphicCase(masm, receiver, name, vector, slot, feedback, 4454 HandleMonomorphicCase(masm, receiver, receiver_map, feedback, vector,
4478 integer_slot, &miss); 4455 integer_slot, &compare_map, &load_smi_map, &try_array);
4479 4456
4480 // Is it a fixed array? 4457 // Is it a fixed array?
4481 __ bind(&try_array); 4458 __ bind(&try_array);
4482 __ CompareRoot(FieldOperand(feedback, 0), Heap::kFixedArrayMapRootIndex); 4459 __ CompareRoot(FieldOperand(feedback, 0), Heap::kFixedArrayMapRootIndex);
4483 __ j(not_equal, &not_array); 4460 __ j(not_equal, &not_array);
4484 HandleArrayCases(masm, receiver, name, vector, slot, feedback, integer_slot, 4461 HandleArrayCases(masm, receiver, name, vector, slot, feedback, receiver_map,
4485 r9, r11, r15, true, &miss); 4462 integer_slot, r11, r15, true, &miss);
4486 4463
4487 __ bind(&not_array); 4464 __ bind(&not_array);
4488 __ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex); 4465 __ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex);
4489 __ j(not_equal, &miss); 4466 __ j(not_equal, &miss);
4490 Code::Flags code_flags = Code::RemoveTypeAndHolderFromFlags( 4467 Code::Flags code_flags = Code::RemoveTypeAndHolderFromFlags(
4491 Code::ComputeHandlerFlags(Code::LOAD_IC)); 4468 Code::ComputeHandlerFlags(Code::LOAD_IC));
4492 masm->isolate()->stub_cache()->GenerateProbe( 4469 masm->isolate()->stub_cache()->GenerateProbe(
4493 masm, Code::LOAD_IC, code_flags, false, receiver, name, feedback, no_reg); 4470 masm, Code::LOAD_IC, code_flags, false, receiver, name, feedback, no_reg);
4494 4471
4495 __ bind(&miss); 4472 __ bind(&miss);
4496 LoadIC::GenerateMiss(masm); 4473 LoadIC::GenerateMiss(masm);
4474
4475 __ bind(&load_smi_map);
4476 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex);
4477 __ jmp(&compare_map);
4497 } 4478 }
4498 4479
4499 4480
4500 void VectorRawKeyedLoadStub::Generate(MacroAssembler* masm) { 4481 void VectorRawKeyedLoadStub::Generate(MacroAssembler* masm) {
4501 GenerateImpl(masm, false); 4482 GenerateImpl(masm, false);
4502 } 4483 }
4503 4484
4504 4485
4505 void VectorRawKeyedLoadStub::GenerateForTrampoline(MacroAssembler* masm) { 4486 void VectorRawKeyedLoadStub::GenerateForTrampoline(MacroAssembler* masm) {
4506 GenerateImpl(masm, true); 4487 GenerateImpl(masm, true);
4507 } 4488 }
4508 4489
4509 4490
4510 void VectorRawKeyedLoadStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { 4491 void VectorRawKeyedLoadStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
4511 Register receiver = VectorLoadICDescriptor::ReceiverRegister(); // rdx 4492 Register receiver = VectorLoadICDescriptor::ReceiverRegister(); // rdx
4512 Register key = VectorLoadICDescriptor::NameRegister(); // rcx 4493 Register key = VectorLoadICDescriptor::NameRegister(); // rcx
4513 Register vector = VectorLoadICDescriptor::VectorRegister(); // rbx 4494 Register vector = VectorLoadICDescriptor::VectorRegister(); // rbx
4514 Register slot = VectorLoadICDescriptor::SlotRegister(); // rax 4495 Register slot = VectorLoadICDescriptor::SlotRegister(); // rax
4515 Register feedback = rdi; 4496 Register feedback = rdi;
4516 Register integer_slot = r8; 4497 Register integer_slot = r8;
4498 Register receiver_map = r9;
4517 4499
4518 __ SmiToInteger32(integer_slot, slot); 4500 __ SmiToInteger32(integer_slot, slot);
4519 __ movp(feedback, FieldOperand(vector, integer_slot, times_pointer_size, 4501 __ movp(feedback, FieldOperand(vector, integer_slot, times_pointer_size,
4520 FixedArray::kHeaderSize)); 4502 FixedArray::kHeaderSize));
4521 4503
4522 // Is it a weak cell? 4504 // Try to quickly handle the monomorphic case without knowing for sure
4523 Label try_array; 4505 // if we have a weak cell in feedback. We do know it's safe to look
4524 Label not_array, smi_key, key_okay, miss; 4506 // at WeakCell::kValueOffset.
4525 __ CompareRoot(FieldOperand(feedback, 0), Heap::kWeakCellMapRootIndex); 4507 Label try_array, load_smi_map, compare_map;
4526 __ j(not_equal, &try_array); 4508 Label not_array, miss;
4527 HandleMonomorphicCase(masm, receiver, key, vector, slot, feedback, 4509 HandleMonomorphicCase(masm, receiver, receiver_map, feedback, vector,
4528 integer_slot, &miss); 4510 integer_slot, &compare_map, &load_smi_map, &try_array);
4529 4511
4530 __ bind(&try_array); 4512 __ bind(&try_array);
4531 // Is it a fixed array? 4513 // Is it a fixed array?
4532 __ CompareRoot(FieldOperand(feedback, 0), Heap::kFixedArrayMapRootIndex); 4514 __ CompareRoot(FieldOperand(feedback, 0), Heap::kFixedArrayMapRootIndex);
4533 __ j(not_equal, &not_array); 4515 __ j(not_equal, &not_array);
4534 4516
4535 // We have a polymorphic element handler. 4517 // We have a polymorphic element handler.
4536 Label polymorphic, try_poly_name; 4518 Label polymorphic, try_poly_name;
4537 __ bind(&polymorphic); 4519 __ bind(&polymorphic);
4538 HandleArrayCases(masm, receiver, key, vector, slot, feedback, integer_slot, 4520 HandleArrayCases(masm, receiver, key, vector, slot, feedback, receiver_map,
4539 r9, r11, r15, true, &miss); 4521 integer_slot, r11, r15, true, &miss);
4540 4522
4541 __ bind(&not_array); 4523 __ bind(&not_array);
4542 // Is it generic? 4524 // Is it generic?
4543 __ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex); 4525 __ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex);
4544 __ j(not_equal, &try_poly_name); 4526 __ j(not_equal, &try_poly_name);
4545 Handle<Code> megamorphic_stub = 4527 Handle<Code> megamorphic_stub =
4546 KeyedLoadIC::ChooseMegamorphicStub(masm->isolate()); 4528 KeyedLoadIC::ChooseMegamorphicStub(masm->isolate());
4547 __ jmp(megamorphic_stub, RelocInfo::CODE_TARGET); 4529 __ jmp(megamorphic_stub, RelocInfo::CODE_TARGET);
4548 4530
4549 __ bind(&try_poly_name); 4531 __ bind(&try_poly_name);
4550 // We might have a name in feedback, and a fixed array in the next slot. 4532 // We might have a name in feedback, and a fixed array in the next slot.
4551 __ cmpp(key, feedback); 4533 __ cmpp(key, feedback);
4552 __ j(not_equal, &miss); 4534 __ j(not_equal, &miss);
4553 // If the name comparison succeeded, we know we have a fixed array with 4535 // If the name comparison succeeded, we know we have a fixed array with
4554 // at least one map/handler pair. 4536 // at least one map/handler pair.
4555 __ movp(feedback, FieldOperand(vector, integer_slot, times_pointer_size, 4537 __ movp(feedback, FieldOperand(vector, integer_slot, times_pointer_size,
4556 FixedArray::kHeaderSize + kPointerSize)); 4538 FixedArray::kHeaderSize + kPointerSize));
4557 HandleArrayCases(masm, receiver, key, vector, slot, feedback, integer_slot, 4539 HandleArrayCases(masm, receiver, key, vector, slot, feedback, receiver_map,
4558 r9, r11, r15, false, &miss); 4540 integer_slot, r11, r15, false, &miss);
4559 4541
4560 __ bind(&miss); 4542 __ bind(&miss);
4561 KeyedLoadIC::GenerateMiss(masm); 4543 KeyedLoadIC::GenerateMiss(masm);
4544
4545 __ bind(&load_smi_map);
4546 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex);
4547 __ jmp(&compare_map);
4562 } 4548 }
4563 4549
4564 4550
4565 void CallICTrampolineStub::Generate(MacroAssembler* masm) { 4551 void CallICTrampolineStub::Generate(MacroAssembler* masm) {
4566 EmitLoadTypeFeedbackVector(masm, rbx); 4552 EmitLoadTypeFeedbackVector(masm, rbx);
4567 CallICStub stub(isolate(), state()); 4553 CallICStub stub(isolate(), state());
4568 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); 4554 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
4569 } 4555 }
4570 4556
4571 4557
(...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after
5358 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, getter_arg, 5344 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, getter_arg,
5359 kStackSpace, nullptr, return_value_operand, NULL); 5345 kStackSpace, nullptr, return_value_operand, NULL);
5360 } 5346 }
5361 5347
5362 5348
5363 #undef __ 5349 #undef __
5364 5350
5365 } } // namespace v8::internal 5351 } } // namespace v8::internal
5366 5352
5367 #endif // V8_TARGET_ARCH_X64 5353 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/arm64/code-stubs-arm64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698