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

Unified Diff: src/builtins/builtins-internal.cc

Issue 2218703003: [turbofan] Add support for copy-on-write element stores. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix off-by-one loop iteration count. Created 4 years, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/builtins/builtins.h ('k') | src/code-factory.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins/builtins-internal.cc
diff --git a/src/builtins/builtins-internal.cc b/src/builtins/builtins-internal.cc
index 82ff1534ebaec7e22a7a86eb369d9777781d94e2..03728764c6ace49613316280896869472f48fbe1 100644
--- a/src/builtins/builtins-internal.cc
+++ b/src/builtins/builtins-internal.cc
@@ -4,7 +4,7 @@
#include "src/builtins/builtins.h"
#include "src/builtins/builtins-utils.h"
-
+#include "src/interface-descriptors.h"
#include "src/macro-assembler.h"
namespace v8 {
@@ -50,5 +50,132 @@ void Builtins::Generate_StackCheck(MacroAssembler* masm) {
masm->TailCallRuntime(Runtime::kStackGuard);
}
+// -----------------------------------------------------------------------------
+// FixedArray helpers.
+
+void Builtins::Generate_CopyFixedArray(CodeStubAssembler* assembler) {
+ typedef CodeStubAssembler::Label Label;
+ typedef compiler::Node Node;
+ typedef CodeStubAssembler::Variable Variable;
+ typedef CopyFixedArrayDescriptor Descriptor;
+
+ Node* source = assembler->Parameter(Descriptor::kSource);
+
+ // Load the {source} length.
+ Node* source_length_tagged =
+ assembler->LoadObjectField(source, FixedArray::kLengthOffset);
+ Node* source_length = assembler->SmiToWord(source_length_tagged);
+
+ // Compute the size of {source} in bytes.
+ Node* source_size = assembler->IntPtrAdd(
+ assembler->WordShl(source_length,
+ assembler->IntPtrConstant(kPointerSizeLog2)),
+ assembler->IntPtrConstant(FixedArray::kHeaderSize));
+
+ // Check if we can allocate in new space.
+ Label if_newspace(assembler), if_oldspace(assembler);
+ assembler->Branch(assembler->UintPtrLessThan(
+ source_size, assembler->IntPtrConstant(
+ Page::kMaxRegularHeapObjectSize)),
+ &if_newspace, &if_oldspace);
+
+ assembler->Bind(&if_newspace);
+ {
+ // Allocate the targeting FixedArray in new space.
+ Node* target = assembler->Allocate(source_size);
+ assembler->StoreMapNoWriteBarrier(
+ target, assembler->LoadRoot(Heap::kFixedArrayMapRootIndex));
+ assembler->StoreObjectFieldNoWriteBarrier(target, FixedArray::kLengthOffset,
+ source_length_tagged);
+
+ // Compute the limit.
+ Node* limit = assembler->IntPtrSub(
+ source_size, assembler->IntPtrConstant(kHeapObjectTag));
+
+ // Copy the {source} to the {target}.
+ Variable var_offset(assembler, MachineType::PointerRepresentation());
+ Label loop(assembler, &var_offset), done_loop(assembler);
+ var_offset.Bind(
+ assembler->IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag));
+ assembler->Goto(&loop);
+ assembler->Bind(&loop);
+ {
+ // Determine the current {offset}.
+ Node* offset = var_offset.value();
+
+ // Check if we are done.
+ assembler->GotoUnless(assembler->UintPtrLessThan(offset, limit),
+ &done_loop);
+
+ // Load the value from {source}.
+ Node* value = assembler->Load(MachineType::AnyTagged(), source, offset);
+
+ // Store the {value} to the {target} without a write barrier, since we
+ // know that the {target} is allocated in new space.
+ assembler->StoreNoWriteBarrier(MachineRepresentation::kTagged, target,
+ offset, value);
+
+ // Increment {offset} and continue.
+ var_offset.Bind(assembler->IntPtrAdd(
+ offset, assembler->IntPtrConstant(kPointerSize)));
+ assembler->Goto(&loop);
+ }
+
+ assembler->Bind(&done_loop);
+ assembler->Return(target);
+ }
+
+ assembler->Bind(&if_oldspace);
+ {
+ // Allocate the targeting FixedArray in old space
+ // (maybe even in large object space).
+ Node* flags = assembler->SmiConstant(
+ Smi::FromInt(AllocateDoubleAlignFlag::encode(false) |
+ AllocateTargetSpace::encode(AllocationSpace::OLD_SPACE)));
+ Node* source_size_tagged = assembler->SmiFromWord(source_size);
+ Node* target = assembler->CallRuntime(Runtime::kAllocateInTargetSpace,
+ assembler->NoContextConstant(),
+ source_size_tagged, flags);
+ assembler->StoreMapNoWriteBarrier(
+ target, assembler->LoadRoot(Heap::kFixedArrayMapRootIndex));
+ assembler->StoreObjectFieldNoWriteBarrier(target, FixedArray::kLengthOffset,
+ source_length_tagged);
+
+ // Compute the limit.
+ Node* limit = assembler->IntPtrSub(
+ source_size, assembler->IntPtrConstant(kHeapObjectTag));
+
+ // Copy the {source} to the {target}.
+ Variable var_offset(assembler, MachineType::PointerRepresentation());
+ Label loop(assembler, &var_offset), done_loop(assembler);
+ var_offset.Bind(
+ assembler->IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag));
+ assembler->Goto(&loop);
+ assembler->Bind(&loop);
+ {
+ // Determine the current {offset}.
+ Node* offset = var_offset.value();
+
+ // Check if we are done.
+ assembler->GotoUnless(assembler->UintPtrLessThan(offset, limit),
+ &done_loop);
+
+ // Load the value from {source}.
+ Node* value = assembler->Load(MachineType::AnyTagged(), source, offset);
+
+ // Store the {value} to the {target} with a proper write barrier.
+ assembler->Store(MachineRepresentation::kTagged, target, offset, value);
+
+ // Increment {offset} and continue.
+ var_offset.Bind(assembler->IntPtrAdd(
+ offset, assembler->IntPtrConstant(kPointerSize)));
+ assembler->Goto(&loop);
+ }
+
+ assembler->Bind(&done_loop);
+ assembler->Return(target);
+ }
+}
+
} // namespace internal
} // namespace v8
« no previous file with comments | « src/builtins/builtins.h ('k') | src/code-factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698