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

Side by Side Diff: src/arm/code-stubs-arm.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/arm/assembler-arm.h ('k') | src/arm64/code-stubs-arm64.cc » ('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 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_ARM 7 #if V8_TARGET_ARCH_ARM
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 4351 matching lines...) Expand 10 before | Expand all | Expand 10 after
4362 } 4362 }
4363 4363
4364 4364
4365 void VectorRawLoadStub::GenerateForTrampoline(MacroAssembler* masm) { 4365 void VectorRawLoadStub::GenerateForTrampoline(MacroAssembler* masm) {
4366 GenerateImpl(masm, true); 4366 GenerateImpl(masm, true);
4367 } 4367 }
4368 4368
4369 4369
4370 static void HandleArrayCases(MacroAssembler* masm, Register receiver, 4370 static void HandleArrayCases(MacroAssembler* masm, Register receiver,
4371 Register key, Register vector, Register slot, 4371 Register key, Register vector, Register slot,
4372 Register feedback, Register scratch1, 4372 Register feedback, Register receiver_map,
4373 Register scratch2, Register scratch3, 4373 Register scratch1, Register scratch2,
4374 bool is_polymorphic, Label* miss) { 4374 bool is_polymorphic, Label* miss) {
4375 // feedback initially contains the feedback array 4375 // feedback initially contains the feedback array
4376 Label next_loop, prepare_next; 4376 Label next_loop, prepare_next;
4377 Label load_smi_map, compare_map;
4378 Label start_polymorphic; 4377 Label start_polymorphic;
4379 4378
4380 Register receiver_map = scratch1; 4379 Register cached_map = scratch1;
4381 Register cached_map = scratch2;
4382 4380
4383 // Receiver might not be a heap object.
4384 __ JumpIfSmi(receiver, &load_smi_map);
4385 __ ldr(receiver_map, FieldMemOperand(receiver, HeapObject::kMapOffset));
4386 __ bind(&compare_map);
4387 __ ldr(cached_map, 4381 __ ldr(cached_map,
4388 FieldMemOperand(feedback, FixedArray::OffsetOfElementAt(0))); 4382 FieldMemOperand(feedback, FixedArray::OffsetOfElementAt(0)));
4389 __ ldr(cached_map, FieldMemOperand(cached_map, WeakCell::kValueOffset)); 4383 __ ldr(cached_map, FieldMemOperand(cached_map, WeakCell::kValueOffset));
4390 __ cmp(receiver_map, cached_map); 4384 __ cmp(receiver_map, cached_map);
4391 __ b(ne, &start_polymorphic); 4385 __ b(ne, &start_polymorphic);
4392 // found, now call handler. 4386 // found, now call handler.
4393 Register handler = feedback; 4387 Register handler = feedback;
4394 __ ldr(handler, FieldMemOperand(feedback, FixedArray::OffsetOfElementAt(1))); 4388 __ ldr(handler, FieldMemOperand(feedback, FixedArray::OffsetOfElementAt(1)));
4395 __ add(pc, handler, Operand(Code::kHeaderSize - kHeapObjectTag)); 4389 __ add(pc, handler, Operand(Code::kHeaderSize - kHeapObjectTag));
4396 4390
4397 4391
4398 Register length = scratch3; 4392 Register length = scratch2;
4399 __ bind(&start_polymorphic); 4393 __ bind(&start_polymorphic);
4400 __ ldr(length, FieldMemOperand(feedback, FixedArray::kLengthOffset)); 4394 __ ldr(length, FieldMemOperand(feedback, FixedArray::kLengthOffset));
4401 if (!is_polymorphic) { 4395 if (!is_polymorphic) {
4402 // If the IC could be monomorphic we have to make sure we don't go past the 4396 // If the IC could be monomorphic we have to make sure we don't go past the
4403 // end of the feedback array. 4397 // end of the feedback array.
4404 __ cmp(length, Operand(Smi::FromInt(2))); 4398 __ cmp(length, Operand(Smi::FromInt(2)));
4405 __ b(eq, miss); 4399 __ b(eq, miss);
4406 } 4400 }
4407 4401
4408 Register too_far = length; 4402 Register too_far = length;
4409 Register pointer_reg = feedback; 4403 Register pointer_reg = feedback;
4410 4404
4411 // +-----+------+------+-----+-----+ ... ----+ 4405 // +-----+------+------+-----+-----+ ... ----+
4412 // | map | len | wm0 | h0 | wm1 | hN | 4406 // | map | len | wm0 | h0 | wm1 | hN |
4413 // +-----+------+------+-----+-----+ ... ----+ 4407 // +-----+------+------+-----+-----+ ... ----+
4414 // 0 1 2 len-1 4408 // 0 1 2 len-1
4415 // ^ ^ 4409 // ^ ^
4416 // | | 4410 // | |
4417 // pointer_reg too_far 4411 // pointer_reg too_far
4418 // aka feedback scratch3 4412 // aka feedback scratch2
4419 // also need receiver_map (aka scratch1) 4413 // also need receiver_map
4420 // use cached_map (scratch2) to look in the weak map values. 4414 // use cached_map (scratch1) to look in the weak map values.
4421 __ add(too_far, feedback, Operand::PointerOffsetFromSmiKey(length)); 4415 __ add(too_far, feedback, Operand::PointerOffsetFromSmiKey(length));
4422 __ add(too_far, too_far, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 4416 __ add(too_far, too_far, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
4423 __ add(pointer_reg, feedback, 4417 __ add(pointer_reg, feedback,
4424 Operand(FixedArray::OffsetOfElementAt(2) - kHeapObjectTag)); 4418 Operand(FixedArray::OffsetOfElementAt(2) - kHeapObjectTag));
4425 4419
4426 __ bind(&next_loop); 4420 __ bind(&next_loop);
4427 __ ldr(cached_map, MemOperand(pointer_reg)); 4421 __ ldr(cached_map, MemOperand(pointer_reg));
4428 __ ldr(cached_map, FieldMemOperand(cached_map, WeakCell::kValueOffset)); 4422 __ ldr(cached_map, FieldMemOperand(cached_map, WeakCell::kValueOffset));
4429 __ cmp(receiver_map, cached_map); 4423 __ cmp(receiver_map, cached_map);
4430 __ b(ne, &prepare_next); 4424 __ b(ne, &prepare_next);
4431 __ ldr(handler, MemOperand(pointer_reg, kPointerSize)); 4425 __ ldr(handler, MemOperand(pointer_reg, kPointerSize));
4432 __ add(pc, handler, Operand(Code::kHeaderSize - kHeapObjectTag)); 4426 __ add(pc, handler, Operand(Code::kHeaderSize - kHeapObjectTag));
4433 4427
4434 __ bind(&prepare_next); 4428 __ bind(&prepare_next);
4435 __ add(pointer_reg, pointer_reg, Operand(kPointerSize * 2)); 4429 __ add(pointer_reg, pointer_reg, Operand(kPointerSize * 2));
4436 __ cmp(pointer_reg, too_far); 4430 __ cmp(pointer_reg, too_far);
4437 __ b(lt, &next_loop); 4431 __ b(lt, &next_loop);
4438 4432
4439 // We exhausted our array of map handler pairs. 4433 // We exhausted our array of map handler pairs.
4440 __ jmp(miss); 4434 __ jmp(miss);
4441
4442 __ bind(&load_smi_map);
4443 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex);
4444 __ jmp(&compare_map);
4445 } 4435 }
4446 4436
4447 4437
4448 static void HandleMonomorphicCase(MacroAssembler* masm, Register receiver, 4438 static void HandleMonomorphicCase(MacroAssembler* masm, Register receiver,
4449 Register key, Register vector, Register slot, 4439 Register receiver_map, Register feedback,
4450 Register weak_cell, Register scratch, 4440 Register vector, Register slot,
4451 Label* miss) { 4441 Register scratch, Label* compare_map,
4452 // feedback initially contains the feedback array 4442 Label* load_smi_map, Label* try_array) {
4453 Label compare_smi_map; 4443 __ JumpIfSmi(receiver, load_smi_map);
4454 Register receiver_map = scratch; 4444 __ ldr(receiver_map, FieldMemOperand(receiver, HeapObject::kMapOffset));
4455 Register cached_map = weak_cell; 4445 __ bind(compare_map);
4456 4446 Register cached_map = scratch;
4457 // Move the weak map into the weak_cell register. 4447 // Move the weak map into the weak_cell register.
4458 __ ldr(cached_map, FieldMemOperand(weak_cell, WeakCell::kValueOffset)); 4448 __ ldr(cached_map, FieldMemOperand(feedback, WeakCell::kValueOffset));
4459
4460 // Receiver might not be a heap object.
4461 __ JumpIfSmi(receiver, &compare_smi_map);
4462 __ ldr(receiver_map, FieldMemOperand(receiver, HeapObject::kMapOffset));
4463 __ cmp(cached_map, receiver_map); 4449 __ cmp(cached_map, receiver_map);
4464 __ b(ne, miss); 4450 __ b(ne, try_array);
4465 4451 Register handler = feedback;
4466 Register handler = weak_cell;
4467 __ add(handler, vector, Operand::PointerOffsetFromSmiKey(slot)); 4452 __ add(handler, vector, Operand::PointerOffsetFromSmiKey(slot));
4468 __ ldr(handler, 4453 __ ldr(handler,
4469 FieldMemOperand(handler, FixedArray::kHeaderSize + kPointerSize)); 4454 FieldMemOperand(handler, FixedArray::kHeaderSize + kPointerSize));
4470 __ add(pc, handler, Operand(Code::kHeaderSize - kHeapObjectTag));
4471
4472 // In microbenchmarks, it made sense to unroll this code so that the call to
4473 // the handler is duplicated for a HeapObject receiver and a Smi receiver.
4474 __ bind(&compare_smi_map);
4475 __ CompareRoot(weak_cell, Heap::kHeapNumberMapRootIndex);
4476 __ b(ne, miss);
4477 __ add(handler, vector, Operand::PointerOffsetFromSmiKey(slot));
4478 __ ldr(handler,
4479 FieldMemOperand(handler, FixedArray::kHeaderSize + kPointerSize));
4480 __ add(pc, handler, Operand(Code::kHeaderSize - kHeapObjectTag)); 4455 __ add(pc, handler, Operand(Code::kHeaderSize - kHeapObjectTag));
4481 } 4456 }
4482 4457
4483 4458
4484 void VectorRawLoadStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { 4459 void VectorRawLoadStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
4485 Register receiver = VectorLoadICDescriptor::ReceiverRegister(); // r1 4460 Register receiver = VectorLoadICDescriptor::ReceiverRegister(); // r1
4486 Register name = VectorLoadICDescriptor::NameRegister(); // r2 4461 Register name = VectorLoadICDescriptor::NameRegister(); // r2
4487 Register vector = VectorLoadICDescriptor::VectorRegister(); // r3 4462 Register vector = VectorLoadICDescriptor::VectorRegister(); // r3
4488 Register slot = VectorLoadICDescriptor::SlotRegister(); // r0 4463 Register slot = VectorLoadICDescriptor::SlotRegister(); // r0
4489 Register feedback = r4; 4464 Register feedback = r4;
4490 Register scratch1 = r5; 4465 Register receiver_map = r5;
4466 Register scratch1 = r8;
4491 4467
4492 __ add(feedback, vector, Operand::PointerOffsetFromSmiKey(slot)); 4468 __ add(feedback, vector, Operand::PointerOffsetFromSmiKey(slot));
4493 __ ldr(feedback, FieldMemOperand(feedback, FixedArray::kHeaderSize)); 4469 __ ldr(feedback, FieldMemOperand(feedback, FixedArray::kHeaderSize));
4494 4470
4495 // Is it a weak cell? 4471 // Try to quickly handle the monomorphic case without knowing for sure
4496 Label try_array; 4472 // if we have a weak cell in feedback. We do know it's safe to look
4497 Label not_array, smi_key, key_okay, miss; 4473 // at WeakCell::kValueOffset.
4498 __ ldr(scratch1, FieldMemOperand(feedback, HeapObject::kMapOffset)); 4474 Label try_array, load_smi_map, compare_map;
4499 __ CompareRoot(scratch1, Heap::kWeakCellMapRootIndex); 4475 Label not_array, miss;
4500 __ b(ne, &try_array); 4476 HandleMonomorphicCase(masm, receiver, receiver_map, feedback, vector, slot,
4501 HandleMonomorphicCase(masm, receiver, name, vector, slot, feedback, scratch1, 4477 scratch1, &compare_map, &load_smi_map, &try_array);
4502 &miss);
4503 4478
4504 // Is it a fixed array? 4479 // Is it a fixed array?
4505 __ bind(&try_array); 4480 __ bind(&try_array);
4481 __ ldr(scratch1, FieldMemOperand(feedback, HeapObject::kMapOffset));
4506 __ CompareRoot(scratch1, Heap::kFixedArrayMapRootIndex); 4482 __ CompareRoot(scratch1, Heap::kFixedArrayMapRootIndex);
4507 __ b(ne, &not_array); 4483 __ b(ne, &not_array);
4508 HandleArrayCases(masm, receiver, name, vector, slot, feedback, scratch1, r8, 4484 HandleArrayCases(masm, receiver, name, vector, slot, feedback, receiver_map,
4509 r9, true, &miss); 4485 scratch1, r9, true, &miss);
4510 4486
4511 __ bind(&not_array); 4487 __ bind(&not_array);
4512 __ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex); 4488 __ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex);
4513 __ b(ne, &miss); 4489 __ b(ne, &miss);
4514 Code::Flags code_flags = Code::RemoveTypeAndHolderFromFlags( 4490 Code::Flags code_flags = Code::RemoveTypeAndHolderFromFlags(
4515 Code::ComputeHandlerFlags(Code::LOAD_IC)); 4491 Code::ComputeHandlerFlags(Code::LOAD_IC));
4516 masm->isolate()->stub_cache()->GenerateProbe(masm, Code::LOAD_IC, code_flags, 4492 masm->isolate()->stub_cache()->GenerateProbe(masm, Code::LOAD_IC, code_flags,
4517 false, receiver, name, feedback, 4493 false, receiver, name, feedback,
4518 scratch1, r8, r9); 4494 receiver_map, scratch1, r9);
4519 4495
4520 __ bind(&miss); 4496 __ bind(&miss);
4521 LoadIC::GenerateMiss(masm); 4497 LoadIC::GenerateMiss(masm);
4498
4499
4500 __ bind(&load_smi_map);
4501 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex);
4502 __ jmp(&compare_map);
4522 } 4503 }
4523 4504
4524 4505
4525 void VectorRawKeyedLoadStub::Generate(MacroAssembler* masm) { 4506 void VectorRawKeyedLoadStub::Generate(MacroAssembler* masm) {
4526 GenerateImpl(masm, false); 4507 GenerateImpl(masm, false);
4527 } 4508 }
4528 4509
4529 4510
4530 void VectorRawKeyedLoadStub::GenerateForTrampoline(MacroAssembler* masm) { 4511 void VectorRawKeyedLoadStub::GenerateForTrampoline(MacroAssembler* masm) {
4531 GenerateImpl(masm, true); 4512 GenerateImpl(masm, true);
4532 } 4513 }
4533 4514
4534 4515
4535 void VectorRawKeyedLoadStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { 4516 void VectorRawKeyedLoadStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
4536 Register receiver = VectorLoadICDescriptor::ReceiverRegister(); // r1 4517 Register receiver = VectorLoadICDescriptor::ReceiverRegister(); // r1
4537 Register key = VectorLoadICDescriptor::NameRegister(); // r2 4518 Register key = VectorLoadICDescriptor::NameRegister(); // r2
4538 Register vector = VectorLoadICDescriptor::VectorRegister(); // r3 4519 Register vector = VectorLoadICDescriptor::VectorRegister(); // r3
4539 Register slot = VectorLoadICDescriptor::SlotRegister(); // r0 4520 Register slot = VectorLoadICDescriptor::SlotRegister(); // r0
4540 Register feedback = r4; 4521 Register feedback = r4;
4541 Register scratch1 = r5; 4522 Register receiver_map = r5;
4523 Register scratch1 = r8;
4542 4524
4543 __ add(feedback, vector, Operand::PointerOffsetFromSmiKey(slot)); 4525 __ add(feedback, vector, Operand::PointerOffsetFromSmiKey(slot));
4544 __ ldr(feedback, FieldMemOperand(feedback, FixedArray::kHeaderSize)); 4526 __ ldr(feedback, FieldMemOperand(feedback, FixedArray::kHeaderSize));
4545 4527
4546 // Is it a weak cell? 4528 // Try to quickly handle the monomorphic case without knowing for sure
4547 Label try_array; 4529 // if we have a weak cell in feedback. We do know it's safe to look
4548 Label not_array, smi_key, key_okay, miss; 4530 // at WeakCell::kValueOffset.
4549 __ ldr(scratch1, FieldMemOperand(feedback, HeapObject::kMapOffset)); 4531 Label try_array, load_smi_map, compare_map;
4550 __ CompareRoot(scratch1, Heap::kWeakCellMapRootIndex); 4532 Label not_array, miss;
4551 __ b(ne, &try_array); 4533 HandleMonomorphicCase(masm, receiver, receiver_map, feedback, vector, slot,
4552 HandleMonomorphicCase(masm, receiver, key, vector, slot, feedback, scratch1, 4534 scratch1, &compare_map, &load_smi_map, &try_array);
4553 &miss);
4554 4535
4555 __ bind(&try_array); 4536 __ bind(&try_array);
4556 // Is it a fixed array? 4537 // Is it a fixed array?
4538 __ ldr(scratch1, FieldMemOperand(feedback, HeapObject::kMapOffset));
4557 __ CompareRoot(scratch1, Heap::kFixedArrayMapRootIndex); 4539 __ CompareRoot(scratch1, Heap::kFixedArrayMapRootIndex);
4558 __ b(ne, &not_array); 4540 __ b(ne, &not_array);
4559 4541
4560 // We have a polymorphic element handler. 4542 // We have a polymorphic element handler.
4561 Label polymorphic, try_poly_name; 4543 Label polymorphic, try_poly_name;
4562 __ bind(&polymorphic); 4544 __ bind(&polymorphic);
4563 HandleArrayCases(masm, receiver, key, vector, slot, feedback, scratch1, r8, 4545 HandleArrayCases(masm, receiver, key, vector, slot, feedback, receiver_map,
4564 r9, true, &miss); 4546 scratch1, r9, true, &miss);
4565 4547
4566 __ bind(&not_array); 4548 __ bind(&not_array);
4567 // Is it generic? 4549 // Is it generic?
4568 __ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex); 4550 __ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex);
4569 __ b(ne, &try_poly_name); 4551 __ b(ne, &try_poly_name);
4570 Handle<Code> megamorphic_stub = 4552 Handle<Code> megamorphic_stub =
4571 KeyedLoadIC::ChooseMegamorphicStub(masm->isolate()); 4553 KeyedLoadIC::ChooseMegamorphicStub(masm->isolate());
4572 __ Jump(megamorphic_stub, RelocInfo::CODE_TARGET); 4554 __ Jump(megamorphic_stub, RelocInfo::CODE_TARGET);
4573 4555
4574 __ bind(&try_poly_name); 4556 __ bind(&try_poly_name);
4575 // We might have a name in feedback, and a fixed array in the next slot. 4557 // We might have a name in feedback, and a fixed array in the next slot.
4576 __ cmp(key, feedback); 4558 __ cmp(key, feedback);
4577 __ b(ne, &miss); 4559 __ b(ne, &miss);
4578 // If the name comparison succeeded, we know we have a fixed array with 4560 // If the name comparison succeeded, we know we have a fixed array with
4579 // at least one map/handler pair. 4561 // at least one map/handler pair.
4580 __ add(feedback, vector, Operand::PointerOffsetFromSmiKey(slot)); 4562 __ add(feedback, vector, Operand::PointerOffsetFromSmiKey(slot));
4581 __ ldr(feedback, 4563 __ ldr(feedback,
4582 FieldMemOperand(feedback, FixedArray::kHeaderSize + kPointerSize)); 4564 FieldMemOperand(feedback, FixedArray::kHeaderSize + kPointerSize));
4583 HandleArrayCases(masm, receiver, key, vector, slot, feedback, scratch1, r8, 4565 HandleArrayCases(masm, receiver, key, vector, slot, feedback, receiver_map,
4584 r9, false, &miss); 4566 scratch1, r9, false, &miss);
4585 4567
4586 __ bind(&miss); 4568 __ bind(&miss);
4587 KeyedLoadIC::GenerateMiss(masm); 4569 KeyedLoadIC::GenerateMiss(masm);
4570
4571 __ bind(&load_smi_map);
4572 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex);
4573 __ jmp(&compare_map);
4588 } 4574 }
4589 4575
4590 4576
4591 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { 4577 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) {
4592 if (masm->isolate()->function_entry_hook() != NULL) { 4578 if (masm->isolate()->function_entry_hook() != NULL) {
4593 ProfileEntryHookStub stub(masm->isolate()); 4579 ProfileEntryHookStub stub(masm->isolate());
4594 int code_size = masm->CallStubSize(&stub) + 2 * Assembler::kInstrSize; 4580 int code_size = masm->CallStubSize(&stub) + 2 * Assembler::kInstrSize;
4595 PredictableCodeSizeScope predictable(masm, code_size); 4581 PredictableCodeSizeScope predictable(masm, code_size);
4596 __ push(lr); 4582 __ push(lr);
4597 __ CallStub(&stub); 4583 __ CallStub(&stub);
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after
5289 kStackUnwindSpace, NULL, 5275 kStackUnwindSpace, NULL,
5290 MemOperand(fp, 6 * kPointerSize), NULL); 5276 MemOperand(fp, 6 * kPointerSize), NULL);
5291 } 5277 }
5292 5278
5293 5279
5294 #undef __ 5280 #undef __
5295 5281
5296 } } // namespace v8::internal 5282 } } // namespace v8::internal
5297 5283
5298 #endif // V8_TARGET_ARCH_ARM 5284 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm64/code-stubs-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698