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

Side by Side Diff: src/code-stub-assembler.cc

Issue 2330063002: [stubs] Port StoreFastElementsStub to TurboFan. (Closed)
Patch Set: Created 4 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/code-stub-assembler.h ('k') | src/code-stubs.h » ('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 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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/code-stub-assembler.h" 5 #include "src/code-stub-assembler.h"
6 #include "src/code-factory.h" 6 #include "src/code-factory.h"
7 #include "src/frames-inl.h" 7 #include "src/frames-inl.h"
8 #include "src/frames.h" 8 #include "src/frames.h"
9 #include "src/ic/handler-configuration.h" 9 #include "src/ic/handler-configuration.h"
10 #include "src/ic/stub-cache.h" 10 #include "src/ic/stub-cache.h"
(...skipping 3336 matching lines...) Expand 10 before | Expand all | Expand 10 after
3347 Goto(&return_result); 3347 Goto(&return_result);
3348 3348
3349 Bind(&return_result); 3349 Bind(&return_result);
3350 return var_result.value(); 3350 return var_result.value();
3351 } 3351 }
3352 3352
3353 compiler::Node* CodeStubAssembler::ElementOffsetFromIndex(Node* index_node, 3353 compiler::Node* CodeStubAssembler::ElementOffsetFromIndex(Node* index_node,
3354 ElementsKind kind, 3354 ElementsKind kind,
3355 ParameterMode mode, 3355 ParameterMode mode,
3356 int base_size) { 3356 int base_size) {
3357 bool is_double = IsFastDoubleElementsKind(kind); 3357 int element_size_shift = ElementsKindToShiftSize(kind);
3358 int element_size_shift = is_double ? kDoubleSizeLog2 : kPointerSizeLog2;
3359 int element_size = 1 << element_size_shift; 3358 int element_size = 1 << element_size_shift;
3360 int const kSmiShiftBits = kSmiShiftSize + kSmiTagSize; 3359 int const kSmiShiftBits = kSmiShiftSize + kSmiTagSize;
3361 intptr_t index = 0; 3360 intptr_t index = 0;
3362 bool constant_index = false; 3361 bool constant_index = false;
3363 if (mode == SMI_PARAMETERS) { 3362 if (mode == SMI_PARAMETERS) {
3364 element_size_shift -= kSmiShiftBits; 3363 element_size_shift -= kSmiShiftBits;
3365 constant_index = ToIntPtrConstant(index_node, index); 3364 constant_index = ToIntPtrConstant(index_node, index);
3366 index = index >> kSmiShiftBits; 3365 index = index >> kSmiShiftBits;
3367 } else if (mode == INTEGER_PARAMETERS) { 3366 } else if (mode == INTEGER_PARAMETERS) {
3368 int32_t temp = 0; 3367 int32_t temp = 0;
(...skipping 1080 matching lines...) Expand 10 before | Expand all | Expand 10 after
4449 Node* native_context = LoadNativeContext(context); 4448 Node* native_context = LoadNativeContext(context);
4450 Node* script_context_table = 4449 Node* script_context_table =
4451 LoadContextElement(native_context, Context::SCRIPT_CONTEXT_TABLE_INDEX); 4450 LoadContextElement(native_context, Context::SCRIPT_CONTEXT_TABLE_INDEX);
4452 4451
4453 int offset = 4452 int offset =
4454 ScriptContextTable::GetContextOffset(context_index) - kHeapObjectTag; 4453 ScriptContextTable::GetContextOffset(context_index) - kHeapObjectTag;
4455 return Load(MachineType::AnyTagged(), script_context_table, 4454 return Load(MachineType::AnyTagged(), script_context_table,
4456 IntPtrConstant(offset)); 4455 IntPtrConstant(offset));
4457 } 4456 }
4458 4457
4458 Node* CodeStubAssembler::ClampedToUint8(Node* int32_value) {
4459 Label done(this);
4460 Node* int32_zero = Int32Constant(0);
4461 Node* int32_255 = Int32Constant(255);
4462 Variable var_value(this, MachineRepresentation::kWord32);
4463 var_value.Bind(int32_value);
4464 GotoIf(Uint32LessThanOrEqual(int32_value, int32_255), &done);
4465 var_value.Bind(int32_zero);
4466 GotoIf(Int32LessThan(int32_value, int32_zero), &done);
4467 var_value.Bind(int32_255);
4468 Goto(&done);
4469 Bind(&done);
4470 return var_value.value();
4471 }
4472
4473 namespace {
Benedikt Meurer 2016/09/13 09:08:00 Nit: add empty line.
Igor Sheludko 2016/09/13 10:33:16 Done.
4474 // Converts typed array elements kind to a machine representations.
4475 MachineRepresentation ElementsKindToMachineRepresentation(ElementsKind kind) {
4476 switch (kind) {
4477 case UINT8_CLAMPED_ELEMENTS:
4478 case UINT8_ELEMENTS:
4479 case INT8_ELEMENTS:
4480 return MachineRepresentation::kWord8;
4481 case UINT16_ELEMENTS:
4482 case INT16_ELEMENTS:
4483 return MachineRepresentation::kWord16;
4484 case UINT32_ELEMENTS:
4485 case INT32_ELEMENTS:
4486 return MachineRepresentation::kWord32;
4487 case FLOAT32_ELEMENTS:
4488 return MachineRepresentation::kFloat32;
4489 case FLOAT64_ELEMENTS:
4490 return MachineRepresentation::kFloat64;
4491 default:
4492 UNREACHABLE();
4493 return MachineRepresentation::kNone;
4494 }
4495 }
4496 } // namespace
Benedikt Meurer 2016/09/13 09:08:00 Nit: add empty line.
Igor Sheludko 2016/09/13 10:33:16 Done.
4497
4498 void CodeStubAssembler::StoreElement(Node* elements, ElementsKind kind,
4499 Node* index, Node* value,
4500 ParameterMode mode) {
4501 if (IsFixedTypedArrayElementsKind(kind)) {
4502 if (kind == UINT8_CLAMPED_ELEMENTS) {
4503 value = ClampedToUint8(value);
4504 }
4505 Node* offset = ElementOffsetFromIndex(index, kind, mode, 0);
4506 MachineRepresentation rep = ElementsKindToMachineRepresentation(kind);
4507 StoreNoWriteBarrier(rep, elements, offset, value);
4508 return;
4509 }
4510
4511 WriteBarrierMode barrier_mode =
4512 IsFastSmiElementsKind(kind) ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER;
4513 if (IsFastDoubleElementsKind(kind)) {
4514 // Make sure we do not store signalling NaNs into double arrays.
4515 value = Float64SilenceNaN(value);
4516 StoreFixedDoubleArrayElement(elements, index, value, mode);
4517 } else {
4518 StoreFixedArrayElement(elements, index, value, barrier_mode, mode);
4519 }
4520 }
4521
4522 void CodeStubAssembler::StoreObjectElement(Node* object, Node* key, Node* value,
4523 bool is_jsarray,
4524 ElementsKind elements_kind,
4525 KeyedAccessStoreMode store_mode,
4526 Label* bailout) {
4527 Node* elements = LoadElements(object);
4528 if (IsFastSmiOrObjectElementsKind(elements_kind) &&
4529 store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
4530 // Bailout in case of COW elements.
4531 GotoIf(WordNotEqual(LoadMap(elements),
4532 LoadRoot(Heap::kFixedArrayMapRootIndex)),
4533 bailout);
4534 }
4535 // TODO(ishell): introduce TryToIntPtrOrSmi() and use OptimalParameterMode().
4536 ParameterMode parameter_mode = INTPTR_PARAMETERS;
4537 key = TryToIntptr(key, bailout);
4538
4539 if (IsFixedTypedArrayElementsKind(elements_kind)) {
4540 // Check if buffer has been neutered.
4541 Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset);
4542 Node* bitfield = LoadObjectField(buffer, JSArrayBuffer::kBitFieldOffset,
4543 MachineType::Uint32());
4544 Node* neutered_bit =
4545 Word32And(bitfield, Int32Constant(JSArrayBuffer::WasNeutered::kMask));
4546 GotoUnless(Word32Equal(neutered_bit, Int32Constant(0)), bailout);
4547
4548 // Bounds check.
4549 Node* length = UntagParameter(
4550 LoadObjectField(object, JSTypedArray::kLengthOffset), parameter_mode);
4551
4552 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
4553 GotoUnless(IntPtrLessThan(key, IntPtrOrSmiConstant(0, parameter_mode)),
4554 bailout);
Benedikt Meurer 2016/09/13 09:08:00 Maybe you want to check the upper bound as well, a
Igor Sheludko 2016/09/13 10:33:17 Done. Thanks!
4555 } else {
4556 DCHECK(store_mode == STANDARD_STORE);
Benedikt Meurer 2016/09/13 09:08:00 Nit: DCHECK_EQ
Igor Sheludko 2016/09/13 10:33:16 Done.
4557 GotoUnless(UintPtrLessThan(key, length), bailout);
4558 }
4559 // Backing store = external_pointer + base_pointer.
4560 Node* external_pointer =
4561 LoadObjectField(elements, FixedTypedArrayBase::kExternalPointerOffset,
4562 MachineType::Pointer());
4563 Node* base_pointer =
4564 LoadObjectField(elements, FixedTypedArrayBase::kBasePointerOffset);
4565 Node* backing_store = IntPtrAdd(external_pointer, base_pointer);
Benedikt Meurer 2016/09/13 09:08:00 You must not have a GC afterwards before you store
Igor Sheludko 2016/09/13 10:33:17 Done.
4566
4567 if (IsFixedFloatElementsKind(elements_kind)) {
4568 // TODO(ishell): move float32 truncation into PrepareValueForWrite.
4569 value = PrepareValueForWrite(value, Representation::Double(), bailout);
4570 if (elements_kind == FLOAT32_ELEMENTS) {
4571 value = TruncateFloat64ToFloat32(value);
4572 }
4573 } else {
4574 value = TryToIntptr(value, bailout);
Benedikt Meurer 2016/09/13 09:08:00 Maybe add a TODO here, that JS truncation would be
Igor Sheludko 2016/09/13 10:33:16 Done.
4575 }
4576 return StoreElement(backing_store, elements_kind, key, value,
4577 parameter_mode);
Benedikt Meurer 2016/09/13 09:08:00 You probably need to insert a Retain for the buffe
Igor Sheludko 2016/09/13 10:33:16 I rearranged the code so that the value preparatio
4578 }
4579 DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) ||
4580 IsFastDoubleElementsKind(elements_kind));
4581
4582 Node* length = is_jsarray ? LoadObjectField(object, JSArray::kLengthOffset)
4583 : LoadFixedArrayBaseLength(elements);
4584 length = UntagParameter(length, parameter_mode);
4585
4586 // In case value is stored into a fast smi array, assure that the value is
4587 // a smi before manipulating the backing store. Otherwise the backing store
4588 // may be left in an invalid state.
4589 if (IsFastSmiElementsKind(elements_kind)) {
4590 GotoUnless(WordIsSmi(value), bailout);
4591 } else if (IsFastDoubleElementsKind(elements_kind)) {
4592 value = PrepareValueForWrite(value, Representation::Double(), bailout);
4593 }
4594
4595 if (IsGrowStoreMode(store_mode)) {
4596 elements = CheckForCapacityGrow(object, elements, elements_kind, length,
4597 key, parameter_mode, is_jsarray, bailout);
4598 } else {
4599 GotoUnless(UintPtrLessThan(key, length), bailout);
4600
4601 if ((store_mode == STORE_NO_TRANSITION_HANDLE_COW) &&
4602 IsFastSmiOrObjectElementsKind(elements_kind)) {
4603 elements = CopyElementsOnWrite(object, elements, elements_kind, length,
4604 parameter_mode, bailout);
4605 }
4606 }
4607 StoreElement(elements, elements_kind, key, value, parameter_mode);
4608 }
4609
4610 Node* CodeStubAssembler::CheckForCapacityGrow(Node* object, Node* elements,
4611 ElementsKind kind, Node* length,
4612 Node* key, ParameterMode mode,
4613 bool is_js_array,
4614 Label* bailout) {
4615 Variable checked_elements(this, MachineRepresentation::kTagged);
4616 Label grow_case(this), no_grow_case(this), done(this);
4617
4618 Node* condition;
4619 if (IsHoleyElementsKind(kind)) {
4620 condition = UintPtrGreaterThanOrEqual(key, length);
4621 } else {
4622 condition = WordEqual(key, length);
4623 }
4624 Branch(condition, &grow_case, &no_grow_case);
4625
4626 Bind(&grow_case);
4627 {
4628 Node* current_capacity =
4629 UntagParameter(LoadFixedArrayBaseLength(elements), mode);
4630
4631 checked_elements.Bind(elements);
4632
4633 Label fits_capacity(this);
4634 GotoIf(UintPtrLessThan(key, current_capacity), &fits_capacity);
4635 {
4636 Node* new_elements = TryGrowElementsCapacity(
4637 object, elements, kind, key, current_capacity, mode, bailout);
4638
4639 checked_elements.Bind(new_elements);
4640 Goto(&fits_capacity);
4641 }
4642 Bind(&fits_capacity);
4643
4644 if (is_js_array) {
4645 Node* new_length = IntPtrAdd(key, IntPtrOrSmiConstant(1, mode));
4646 StoreObjectFieldNoWriteBarrier(object, JSArray::kLengthOffset,
4647 TagParameter(new_length, mode));
4648 }
4649
4650 if (kind == FAST_SMI_ELEMENTS) {
Benedikt Meurer 2016/09/13 09:08:00 This shouldn't be necessary, it was only necessary
Igor Sheludko 2016/09/13 10:33:16 Indeed, it's not necessary. Thanks!
4651 // Write zero to ensure that the new element is initialized with some smi.
4652 Node* zero = SmiConstant(Smi::FromInt(0));
4653 StoreFixedArrayElement(checked_elements.value(), key, zero,
4654 SKIP_WRITE_BARRIER, mode);
4655 }
4656
4657 Goto(&done);
4658 }
4659
4660 Bind(&no_grow_case);
4661 {
4662 GotoUnless(UintPtrLessThan(key, length), bailout);
4663 checked_elements.Bind(elements);
4664 Goto(&done);
4665 }
4666
4667 Bind(&done);
4668 return checked_elements.value();
4669 }
4670
4671 Node* CodeStubAssembler::CopyElementsOnWrite(Node* object, Node* elements,
4672 ElementsKind kind, Node* length,
4673 ParameterMode mode,
4674 Label* bailout) {
4675 Variable new_elements_var(this, MachineRepresentation::kTagged);
4676 Label done(this);
4677
4678 new_elements_var.Bind(elements);
4679 GotoUnless(
4680 WordEqual(LoadMap(elements), LoadRoot(Heap::kFixedCOWArrayMapRootIndex)),
4681 &done);
4682 {
4683 Node* capacity = UntagParameter(LoadFixedArrayBaseLength(elements), mode);
4684 Node* new_elements = GrowElementsCapacity(object, elements, kind, kind,
4685 length, capacity, mode, bailout);
4686
4687 new_elements_var.Bind(new_elements);
4688 Goto(&done);
4689 }
4690
4691 Bind(&done);
4692 return new_elements_var.value();
4693 }
4694
4459 Node* CodeStubAssembler::EnumLength(Node* map) { 4695 Node* CodeStubAssembler::EnumLength(Node* map) {
4460 Node* bitfield_3 = LoadMapBitField3(map); 4696 Node* bitfield_3 = LoadMapBitField3(map);
4461 Node* enum_length = BitFieldDecode<Map::EnumLengthBits>(bitfield_3); 4697 Node* enum_length = BitFieldDecode<Map::EnumLengthBits>(bitfield_3);
4462 return SmiTag(enum_length); 4698 return SmiTag(enum_length);
4463 } 4699 }
4464 4700
4465 void CodeStubAssembler::CheckEnumCache(Node* receiver, Label* use_cache, 4701 void CodeStubAssembler::CheckEnumCache(Node* receiver, Label* use_cache,
4466 Label* use_runtime) { 4702 Label* use_runtime) {
4467 Variable current_js_object(this, MachineRepresentation::kTagged); 4703 Variable current_js_object(this, MachineRepresentation::kTagged);
4468 current_js_object.Bind(receiver); 4704 current_js_object.Bind(receiver);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
4536 Heap::kTheHoleValueRootIndex); 4772 Heap::kTheHoleValueRootIndex);
4537 4773
4538 // Store the WeakCell in the feedback vector. 4774 // Store the WeakCell in the feedback vector.
4539 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, 4775 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER,
4540 CodeStubAssembler::SMI_PARAMETERS); 4776 CodeStubAssembler::SMI_PARAMETERS);
4541 return cell; 4777 return cell;
4542 } 4778 }
4543 4779
4544 } // namespace internal 4780 } // namespace internal
4545 } // namespace v8 4781 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/code-stubs.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698