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

Side by Side Diff: src/arm/code-stubs-arm.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
« no previous file with comments | « no previous file | src/arm64/code-stubs-arm64.cc » ('j') | src/code-stubs-hydrogen.cc » ('J')
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"
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 4291 matching lines...) Expand 10 before | Expand all | Expand 10 after
4316 } 4317 }
4317 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); 4318 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE);
4318 __ mov(r1, Operand(r1, LSL, kPointerSizeLog2)); 4319 __ mov(r1, Operand(r1, LSL, kPointerSizeLog2));
4319 __ add(sp, sp, r1); 4320 __ add(sp, sp, r1);
4320 __ Ret(); 4321 __ Ret();
4321 } 4322 }
4322 4323
4323 4324
4324 void LoadICTrampolineStub::Generate(MacroAssembler* masm) { 4325 void LoadICTrampolineStub::Generate(MacroAssembler* masm) {
4325 EmitLoadTypeFeedbackVector(masm, VectorLoadICDescriptor::VectorRegister()); 4326 EmitLoadTypeFeedbackVector(masm, VectorLoadICDescriptor::VectorRegister());
4326 VectorLoadStub stub(isolate(), state()); 4327 VectorRawLoadStub stub(isolate(), state());
4327 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); 4328 stub.GenerateForTrampoline(masm);
4328 } 4329 }
4329 4330
4330 4331
4331 void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) { 4332 void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
4332 EmitLoadTypeFeedbackVector(masm, VectorLoadICDescriptor::VectorRegister()); 4333 EmitLoadTypeFeedbackVector(masm, VectorLoadICDescriptor::VectorRegister());
4333 VectorKeyedLoadStub stub(isolate()); 4334 VectorRawKeyedLoadStub stub(isolate());
4334 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); 4335 stub.GenerateForTrampoline(masm);
4335 } 4336 }
4336 4337
4337 4338
4338 void CallICTrampolineStub::Generate(MacroAssembler* masm) { 4339 void CallICTrampolineStub::Generate(MacroAssembler* masm) {
4339 EmitLoadTypeFeedbackVector(masm, r2); 4340 EmitLoadTypeFeedbackVector(masm, r2);
4340 CallICStub stub(isolate(), state()); 4341 CallICStub stub(isolate(), state());
4341 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); 4342 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
4342 } 4343 }
4343 4344
4344 4345
4345 void CallIC_ArrayTrampolineStub::Generate(MacroAssembler* masm) { 4346 void CallIC_ArrayTrampolineStub::Generate(MacroAssembler* masm) {
4346 EmitLoadTypeFeedbackVector(masm, r2); 4347 EmitLoadTypeFeedbackVector(masm, r2);
4347 CallIC_ArrayStub stub(isolate(), state()); 4348 CallIC_ArrayStub stub(isolate(), state());
4348 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); 4349 __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
4349 } 4350 }
4350 4351
4351 4352
4353 void VectorRawLoadStub::Generate(MacroAssembler* masm) {
4354 GenerateImpl(masm, false);
4355 }
4356
4357
4358 void VectorRawLoadStub::GenerateForTrampoline(MacroAssembler* masm) {
4359 GenerateImpl(masm, true);
4360 }
4361
4362
4363 static void HandleArrayCases(MacroAssembler* masm, Register receiver,
4364 Register key, Register vector, Register slot,
4365 Register feedback, Register scratch1,
4366 Register scratch2, Register scratch3,
4367 Label* miss) {
4368 // feedback initially contains the feedback array
4369 Label next, next_loop, prepare_next;
4370 Label load_smi_map, compare_map;
4371
4372 Register receiver_map = scratch1;
4373 Register array_map = scratch2;
4374
4375 // Receiver might not be a heap object.
4376 __ JumpIfSmi(receiver, &load_smi_map);
4377 __ ldr(receiver_map, FieldMemOperand(receiver, HeapObject::kMapOffset));
4378 __ bind(&compare_map);
4379 __ ldr(array_map,
4380 FieldMemOperand(feedback, FixedArray::OffsetOfElementAt(0)));
4381 __ ldr(array_map, FieldMemOperand(array_map, WeakCell::kValueOffset));
4382 __ cmp(receiver_map, array_map);
4383 __ b(ne, &next);
4384 // found, now call handler.
4385 __ ldr(feedback, FieldMemOperand(feedback, FixedArray::OffsetOfElementAt(1)));
4386 __ add(pc, feedback, Operand(Code::kHeaderSize - kHeapObjectTag));
4387
4388
4389 Register length = scratch3;
4390 __ bind(&next);
4391 __ ldr(length, FieldMemOperand(feedback, FixedArray::kLengthOffset));
4392 __ cmp(length, Operand(Smi::FromInt(2)));
4393 Label start_polymorphic;
4394 __ b(ne, &start_polymorphic);
4395 __ jmp(miss);
4396
4397 Register too_far = length;
4398 Register pointer_reg = feedback;
4399
4400 // +-----+------+------+-----+-----+ ... ----+
4401 // | map | len | wm0 | h0 | wm1 | hN |
4402 // +-----+------+------+-----+-----+ ... ----+
4403 // 0 1 2 len-1
4404 // ^ ^
4405 // | |
4406 // pointer_reg too_far
4407 // aka feedback scratch3
4408 // also need receiver_map (aka scratch1)
4409 // use array_map (scratch2) to look in the weak map values.
4410 __ bind(&start_polymorphic);
4411 __ add(too_far, feedback, Operand::PointerOffsetFromSmiKey(length));
4412 __ add(too_far, too_far, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
4413 __ add(pointer_reg, feedback,
4414 Operand(FixedArray::OffsetOfElementAt(2) - kHeapObjectTag));
4415
4416 __ bind(&next_loop);
4417 __ ldr(array_map, MemOperand(pointer_reg));
4418 __ ldr(array_map, FieldMemOperand(array_map, WeakCell::kValueOffset));
4419 __ cmp(receiver_map, array_map);
4420 __ b(ne, &prepare_next);
4421 __ ldr(array_map, MemOperand(pointer_reg, kPointerSize));
4422 __ add(pc, array_map, Operand(Code::kHeaderSize - kHeapObjectTag));
4423
4424 __ bind(&prepare_next);
4425 __ add(pointer_reg, pointer_reg, Operand(kPointerSize * 2));
4426 __ cmp(pointer_reg, too_far);
4427 __ b(lt, &next_loop);
4428
4429 // We exhausted our array of map handler pairs.
4430 __ jmp(miss);
4431
4432 __ bind(&load_smi_map);
4433 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex);
4434 __ jmp(&compare_map);
4435 }
4436
4437
4438 static void HandleMonomorphicCase(MacroAssembler* masm, Register receiver,
4439 Register key, Register vector, Register slot,
4440 Register weak_cell, Register scratch,
4441 Label* miss) {
4442 // feedback initially contains the feedback array
4443 Label compare_smi_map;
4444
4445 Register receiver_map = scratch;
4446
4447 // Move the weak map into the weak_cell register.
4448 __ ldr(weak_cell, FieldMemOperand(weak_cell, WeakCell::kValueOffset));
4449
4450 // Receiver might not be a heap object.
4451 __ JumpIfSmi(receiver, &compare_smi_map);
4452 __ ldr(receiver_map, FieldMemOperand(receiver, HeapObject::kMapOffset));
4453 __ cmp(weak_cell, receiver_map);
4454 __ b(ne, miss);
4455 __ add(weak_cell, vector, Operand::PointerOffsetFromSmiKey(slot));
4456 __ ldr(weak_cell,
4457 FieldMemOperand(weak_cell, FixedArray::kHeaderSize + kPointerSize));
4458 __ add(pc, weak_cell, Operand(Code::kHeaderSize - kHeapObjectTag));
4459
4460 // In microbenchmarks, it made sense to unroll this code so that the call to
4461 // the handler is duplicated for a HeapObject receiver and a Smi receiver.
4462 // TODO(mvstanton): does this hold on ARM?
4463 __ bind(&compare_smi_map);
4464 __ CompareRoot(weak_cell, Heap::kHeapNumberMapRootIndex);
4465 __ b(ne, miss);
4466 __ add(weak_cell, vector, Operand::PointerOffsetFromSmiKey(slot));
4467 __ ldr(weak_cell,
4468 FieldMemOperand(weak_cell, FixedArray::kHeaderSize + kPointerSize));
4469 __ add(pc, weak_cell, Operand(Code::kHeaderSize - kHeapObjectTag));
4470 }
4471
4472
4473 void VectorRawLoadStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
4474 Register receiver = VectorLoadICDescriptor::ReceiverRegister(); // r1
4475 Register name = VectorLoadICDescriptor::NameRegister(); // r2
4476 Register vector = VectorLoadICDescriptor::VectorRegister(); // r3
4477 Register slot = VectorLoadICDescriptor::SlotRegister(); // r0
4478 Register feedback = r4;
4479 Register scratch1 = r5;
4480
4481 __ add(feedback, vector, Operand::PointerOffsetFromSmiKey(slot));
4482 __ ldr(feedback, FieldMemOperand(feedback, FixedArray::kHeaderSize));
4483
4484 // Is it a weak cell?
4485 Label try_array;
4486 Label not_array, smi_key, key_okay, miss;
4487 __ ldr(scratch1, FieldMemOperand(feedback, HeapObject::kMapOffset));
4488 __ CompareRoot(scratch1, Heap::kWeakCellMapRootIndex);
4489 __ b(ne, &try_array);
4490 HandleMonomorphicCase(masm, receiver, name, vector, slot, feedback, scratch1,
4491 &miss);
4492 __ stop("Unexpected code address");
4493
4494 // Is it a fixed array?
4495 __ bind(&try_array);
4496 __ CompareRoot(scratch1, Heap::kFixedArrayMapRootIndex);
4497 __ b(ne, &not_array);
4498 HandleArrayCases(masm, receiver, name, vector, slot, feedback, scratch1, r8,
4499 r9, &miss);
4500 __ stop("Unexpected code address");
4501
4502 __ bind(&not_array);
4503 __ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex);
4504 __ b(ne, &miss);
4505 Code::Flags code_flags = Code::RemoveTypeAndHolderFromFlags(
4506 Code::ComputeHandlerFlags(Code::LOAD_IC));
4507 masm->isolate()->stub_cache()->GenerateProbe(masm, Code::LOAD_IC, code_flags,
4508 false, receiver, name, feedback,
4509 scratch1, r8, r9);
4510
4511 __ bind(&miss);
4512 LoadIC::GenerateMiss(masm);
4513 }
4514
4515
4516 void VectorRawKeyedLoadStub::Generate(MacroAssembler* masm) {
4517 GenerateImpl(masm, false);
4518 }
4519
4520
4521 void VectorRawKeyedLoadStub::GenerateForTrampoline(MacroAssembler* masm) {
4522 GenerateImpl(masm, true);
4523 }
4524
4525
4526 void VectorRawKeyedLoadStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
4527 Register receiver = VectorLoadICDescriptor::ReceiverRegister(); // r1
4528 Register key = VectorLoadICDescriptor::NameRegister(); // r2
4529 Register vector = VectorLoadICDescriptor::VectorRegister(); // r3
4530 Register slot = VectorLoadICDescriptor::SlotRegister(); // r0
4531 Register feedback = r4;
4532 Register scratch1 = r5;
4533
4534 __ add(feedback, vector, Operand::PointerOffsetFromSmiKey(slot));
4535 __ ldr(feedback, FieldMemOperand(feedback, FixedArray::kHeaderSize));
4536
4537 // Is it a weak cell?
4538 Label try_array;
4539 Label not_array, smi_key, key_okay, miss;
4540 __ ldr(scratch1, FieldMemOperand(feedback, HeapObject::kMapOffset));
4541 __ CompareRoot(scratch1, Heap::kWeakCellMapRootIndex);
4542 __ b(ne, &try_array);
4543 __ JumpIfNotSmi(key, &miss);
4544 HandleMonomorphicCase(masm, receiver, key, vector, slot, feedback, scratch1,
4545 &miss);
4546 __ stop("Unexpected code address");
4547
4548 __ bind(&try_array);
4549 // Is it a fixed array?
4550 __ CompareRoot(scratch1, Heap::kFixedArrayMapRootIndex);
4551 __ b(ne, &not_array);
4552 // We have a polymorphic element handler.
4553 __ JumpIfNotSmi(key, &miss);
4554
4555 Label polymorphic, try_poly_name;
4556 __ bind(&polymorphic);
4557 HandleArrayCases(masm, receiver, key, vector, slot, feedback, scratch1, r8,
4558 r9, &miss);
4559 __ stop("Unexpected code address");
4560
4561 __ bind(&not_array);
4562 // Is it generic?
4563 __ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex);
4564 __ b(ne, &try_poly_name);
4565 Handle<Code> megamorphic_stub =
4566 KeyedLoadIC::ChooseMegamorphicStub(masm->isolate());
4567 __ Jump(megamorphic_stub, RelocInfo::CODE_TARGET);
4568
4569 __ bind(&try_poly_name);
4570 // We might have a name in scratch, and a fixed array in the next slot.
4571 __ cmp(key, scratch1);
4572 __ b(ne, &miss);
4573 // If the name comparison succeeded, we know we have a fixed array with
4574 // at least one map/handler pair.
4575 __ add(feedback, vector, Operand::PointerOffsetFromSmiKey(slot));
4576 __ ldr(feedback,
4577 FieldMemOperand(feedback, FixedArray::kHeaderSize + kPointerSize));
4578 __ jmp(&polymorphic);
4579
4580 __ bind(&miss);
4581 KeyedLoadIC::GenerateMiss(masm);
4582 }
4583
4584
4352 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { 4585 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) {
4353 if (masm->isolate()->function_entry_hook() != NULL) { 4586 if (masm->isolate()->function_entry_hook() != NULL) {
4354 ProfileEntryHookStub stub(masm->isolate()); 4587 ProfileEntryHookStub stub(masm->isolate());
4355 int code_size = masm->CallStubSize(&stub) + 2 * Assembler::kInstrSize; 4588 int code_size = masm->CallStubSize(&stub) + 2 * Assembler::kInstrSize;
4356 PredictableCodeSizeScope predictable(masm, code_size); 4589 PredictableCodeSizeScope predictable(masm, code_size);
4357 __ push(lr); 4590 __ push(lr);
4358 __ CallStub(&stub); 4591 __ CallStub(&stub);
4359 __ pop(lr); 4592 __ pop(lr);
4360 } 4593 }
4361 } 4594 }
(...skipping 692 matching lines...) Expand 10 before | Expand all | Expand 10 after
5054 kStackUnwindSpace, NULL, 5287 kStackUnwindSpace, NULL,
5055 MemOperand(fp, 6 * kPointerSize), NULL); 5288 MemOperand(fp, 6 * kPointerSize), NULL);
5056 } 5289 }
5057 5290
5058 5291
5059 #undef __ 5292 #undef __
5060 5293
5061 } } // namespace v8::internal 5294 } } // namespace v8::internal
5062 5295
5063 #endif // V8_TARGET_ARCH_ARM 5296 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm64/code-stubs-arm64.cc » ('j') | src/code-stubs-hydrogen.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698