Revision: 20034
Author: [email protected]
Date: Tue Mar 18 14:00:21 2014 UTC
Log: A64: Handle a few TODOs.
Below are notes about some of the TODOs handled.
* In Simulator::Debug:
We haven't had issues with printing in the debugger for a while. If the
feature turns out to be still lacking an issue can be raised.
* In SubStringStub::Generate:
There is no need to jump there. The StringCharAtGenerator is asked to
set
the result in x0, and the return sequence following only uses two
instructions.
Also, we would need to jump after the native counter increment instead
of the
return_x0 label.
* In ArrayPushStub::Generate:
Raised an internal issue to check and update the ARM code.
* In MacroAssembler::CopyBytes:
The new code should be faster for bulk copies. Raised an internal issue
to
investigate and improve this function.
* In MacroAssembler::EnterExitFrame:
Unless we actually find something is wrong, this is working and looks
ok.
Also fixed the comments about the FP registers.
* Comment for BumpSystemStackPointer:
Removed the comment at the declaration site and updated the TODO in the
implementation.
[email protected]
Review URL: https://codereview.chromium.org/196473021
http://code.google.com/p/v8/source/detail?r=20034
Modified:
/branches/bleeding_edge/src/a64/code-stubs-a64.cc
/branches/bleeding_edge/src/a64/macro-assembler-a64-inl.h
/branches/bleeding_edge/src/a64/macro-assembler-a64.cc
/branches/bleeding_edge/src/a64/macro-assembler-a64.h
/branches/bleeding_edge/src/a64/simulator-a64.cc
/branches/bleeding_edge/src/a64/stub-cache-a64.cc
/branches/bleeding_edge/src/a64/utils-a64.h
=======================================
--- /branches/bleeding_edge/src/a64/code-stubs-a64.cc Mon Mar 17 15:43:33
2014 UTC
+++ /branches/bleeding_edge/src/a64/code-stubs-a64.cc Tue Mar 18 14:00:21
2014 UTC
@@ -1824,10 +1824,7 @@
__ Mov(x11, Operand(ExternalReference(Isolate::kCEntryFPAddress,
isolate)));
__ Ldr(x10, MemOperand(x11));
- // TODO(all): Pushing the marker twice seems unnecessary.
- // In this case perhaps we could push xzr in the slot for the context
- // (see MAsm::EnterFrame).
- __ Push(x13, x12, x12, x10);
+ __ Push(x13, xzr, x12, x10);
// Set up fp.
__ Sub(fp, jssp, EntryFrameConstants::kCallerFPOffset);
@@ -1873,7 +1870,6 @@
// field in the JSEnv and return a failure sentinel. Coming in here the
// fp will be invalid because the PushTryHandler below sets it to 0 to
// signal the existence of the JSEntry frame.
- // TODO(jbramley): Do this in the Assembler.
__ Mov(x10,
Operand(ExternalReference(Isolate::kPendingExceptionAddress,
isolate)));
}
@@ -4070,12 +4066,13 @@
__ Bind(&update_instance_type);
__ Ldr(temp, FieldMemOperand(unpacked_string, HeapObject::kMapOffset));
__ Ldrb(input_type, FieldMemOperand(temp, Map::kInstanceTypeOffset));
- // TODO(all): This generates "b #+0x4". Can these be optimised out?
- __ B(&underlying_unpacked);
+ // Now control must go to &underlying_unpacked. Since the no code is
generated
+ // before then we fall through instead of generating a useless branch.
__ Bind(&seq_or_external_string);
// Sequential or external string. Registers unpacked_string and
input_string
// alias, so there's nothing to do here.
+ // Note that if code is added here, the above code must be updated.
// x0 result_string pointer to result string object (uninit)
// x1 result_length length of substring result
@@ -4202,7 +4199,6 @@
input_string, from, result_length, x0,
&runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER);
generator.GenerateFast(masm);
- // TODO(jbramley): Why doesn't this jump to return_x0?
__ Drop(3);
__ Ret();
generator.SkipSlow(masm, &runtime);
@@ -4439,7 +4435,6 @@
Operand::UntagSmiAndScale(length, kPointerSizeLog2));
__ Str(value, MemOperand(end_elements, kEndElementsOffset, PreIndex));
} else {
- // TODO(all): ARM has a redundant cmp here.
__ B(gt, &call_builtin);
__ Peek(value, (argc - 1) * kPointerSize);
@@ -5636,7 +5631,6 @@
FrameScope frame_scope(masm, StackFrame::MANUAL);
__ EnterExitFrame(false, x10, kApiStackSpace +
kCallApiFunctionSpillSpace);
- // TODO(all): Optimize this with stp and suchlike.
ASSERT(!AreAliased(x0, api_function_address));
// x0 = FunctionCallbackInfo&
// Arguments is after the return address.
=======================================
--- /branches/bleeding_edge/src/a64/macro-assembler-a64-inl.h Thu Mar 13
09:45:02 2014 UTC
+++ /branches/bleeding_edge/src/a64/macro-assembler-a64-inl.h Tue Mar 18
14:00:21 2014 UTC
@@ -1273,9 +1273,10 @@
ASSERT(!csp.Is(sp_));
// TODO(jbramley): Several callers rely on this not using scratch
registers,
// so we use the assembler directly here. However, this means that large
- // immediate values of 'space' cannot be handled cleanly. Once we
implement
- // our flexible scratch register idea, we could greatly simplify this
- // function.
+ // immediate values of 'space' cannot be handled cleanly. (Only 24-bits
+ // immediates or values of 'space' that can be encoded in one
instruction are
+ // accepted.) Once we implement our flexible scratch register idea, we
could
+ // greatly simplify this function.
InstructionAccurateScope scope(this);
if ((space.IsImmediate()) && !is_uint12(space.immediate())) {
// The subtract instruction supports a 12-bit immediate, shifted left
by
=======================================
--- /branches/bleeding_edge/src/a64/macro-assembler-a64.cc Tue Mar 18
07:13:55 2014 UTC
+++ /branches/bleeding_edge/src/a64/macro-assembler-a64.cc Tue Mar 18
14:00:21 2014 UTC
@@ -737,7 +737,6 @@
void MacroAssembler::Push(const CPURegister& src0, const CPURegister& src1,
const CPURegister& src2, const CPURegister&
src3) {
ASSERT(AreSameSizeAndType(src0, src1, src2, src3));
- ASSERT(src0.IsValid());
int count = 1 + src1.IsValid() + src2.IsValid() + src3.IsValid();
int size = src0.SizeInBytes();
@@ -747,6 +746,21 @@
}
+void MacroAssembler::Push(const CPURegister& src0, const CPURegister& src1,
+ const CPURegister& src2, const CPURegister& src3,
+ const CPURegister& src4, const CPURegister& src5,
+ const CPURegister& src6, const CPURegister&
src7) {
+ ASSERT(AreSameSizeAndType(src0, src1, src2, src3, src4, src5, src6,
src7));
+
+ int count = 5 + src5.IsValid() + src6.IsValid() + src6.IsValid();
+ int size = src0.SizeInBytes();
+
+ PrepareForPush(count, size);
+ PushHelper(4, size, src0, src1, src2, src3);
+ PushHelper(count - 4, size, src4, src5, src6, src7);
+}
+
+
void MacroAssembler::Pop(const CPURegister& dst0, const CPURegister& dst1,
const CPURegister& dst2, const CPURegister& dst3)
{
// It is not valid to pop into the same register more than once in one
@@ -2442,10 +2456,12 @@
Register length,
Register scratch,
CopyHint hint) {
- ASSERT(!AreAliased(src, dst, length, scratch));
+ UseScratchRegisterScope temps(this);
+ Register tmp1 = temps.AcquireX();
+ Register tmp2 = temps.AcquireX();
+ ASSERT(!AreAliased(src, dst, length, scratch, tmp1, tmp2));
+ ASSERT(!AreAliased(src, dst, csp));
- // TODO(all): Implement a faster copy function, and use hint to determine
- // which algorithm to use for copies.
if (emit_debug_code()) {
// Check copy length.
Cmp(length, 0);
@@ -2459,14 +2475,33 @@
Assert(le, kCopyBuffersOverlap);
}
- Label loop, done;
- Cbz(length, &done);
+ Label short_copy, short_loop, bulk_loop, done;
- Bind(&loop);
+ if ((hint == kCopyLong || hint == kCopyUnknown)
&& !FLAG_optimize_for_size) {
+ Register bulk_length = scratch;
+ int pair_size = 2 * kXRegSize;
+ int pair_mask = pair_size - 1;
+
+ Bic(bulk_length, length, pair_mask);
+ Cbz(bulk_length, &short_copy);
+ Bind(&bulk_loop);
+ Sub(bulk_length, bulk_length, pair_size);
+ Ldp(tmp1, tmp2, MemOperand(src, pair_size, PostIndex));
+ Stp(tmp1, tmp2, MemOperand(dst, pair_size, PostIndex));
+ Cbnz(bulk_length, &bulk_loop);
+
+ And(length, length, pair_mask);
+ }
+
+ Bind(&short_copy);
+ Cbz(length, &done);
+ Bind(&short_loop);
Sub(length, length, 1);
- Ldrb(scratch, MemOperand(src, 1, PostIndex));
- Strb(scratch, MemOperand(dst, 1, PostIndex));
- Cbnz(length, &loop);
+ Ldrb(tmp1, MemOperand(src, 1, PostIndex));
+ Strb(tmp1, MemOperand(dst, 1, PostIndex));
+ Cbnz(length, &short_loop);
+
+
Bind(&done);
}
@@ -2945,7 +2980,6 @@
}
-// TODO(jbramley): Check that we're handling the frame pointer correctly.
void MacroAssembler::EnterExitFrame(bool save_doubles,
const Register& scratch,
int extra_space) {
@@ -2989,7 +3023,7 @@
// fp -> fp[0]: CallerFP (old fp)
// fp[-8]: Space reserved for SPOffset.
// fp[-16]: CodeObject()
- // jssp[-16 - fp_size]: Saved doubles (if save_doubles is true).
+ // fp[-16 - fp_size]: Saved doubles (if save_doubles is true).
// jssp[8]: Extra space reserved for caller (if extra_space !=
0).
// jssp -> jssp[0]: Space reserved for the return address.
@@ -3001,7 +3035,7 @@
// fp -> fp[0]: CallerFP (old fp)
// fp[-8]: Space reserved for SPOffset.
// fp[-16]: CodeObject()
- // csp[...]: Saved doubles, if saved_doubles is true.
+ // fp[-16 - fp_size]: Saved doubles (if save_doubles is true).
// csp[8]: Memory reserved for the caller if extra_space != 0.
// Alignment padding, if necessary.
// csp -> csp[0]: Space reserved for the return address.
=======================================
--- /branches/bleeding_edge/src/a64/macro-assembler-a64.h Mon Mar 17
17:18:31 2014 UTC
+++ /branches/bleeding_edge/src/a64/macro-assembler-a64.h Tue Mar 18
14:00:21 2014 UTC
@@ -538,6 +538,10 @@
// the system stack pointer, these methods do not modify any other
registers.
void Push(const CPURegister& src0, const CPURegister& src1 = NoReg,
const CPURegister& src2 = NoReg, const CPURegister& src3 =
NoReg);
+ void Push(const CPURegister& src0, const CPURegister& src1,
+ const CPURegister& src2, const CPURegister& src3,
+ const CPURegister& src4, const CPURegister& src5 = NoReg,
+ const CPURegister& src6 = NoReg, const CPURegister& src7 =
NoReg);
void Pop(const CPURegister& dst0, const CPURegister& dst1 = NoReg,
const CPURegister& dst2 = NoReg, const CPURegister& dst3 =
NoReg);
@@ -791,10 +795,6 @@
//
// This method asserts that StackPointer() is not csp, since the call
does
// not make sense in that context.
- //
- // TODO(jbramley): Currently, this method can only accept values
of 'space'
- // that can be encoded in one instruction. Refer to the implementation
for
- // details.
inline void BumpSystemStackPointer(const Operand& space);
// Helpers
------------------------------------------------------------------
=======================================
--- /branches/bleeding_edge/src/a64/simulator-a64.cc Tue Mar 18 07:13:55
2014 UTC
+++ /branches/bleeding_edge/src/a64/simulator-a64.cc Tue Mar 18 14:00:21
2014 UTC
@@ -304,12 +304,14 @@
// Extending the stack by 2 * 64 bits is required for stack alignment
purposes.
-// TODO(all): Insert a marker in the extra space allocated on the stack.
uintptr_t Simulator::PushAddress(uintptr_t address) {
ASSERT(sizeof(uintptr_t) < 2 * kXRegSize);
intptr_t new_sp = sp() - 2 * kXRegSize;
+ uintptr_t* alignment_slot =
+ reinterpret_cast<uintptr_t*>(new_sp + kXRegSize);
+ memcpy(alignment_slot, &kSlotsZapValue, kPointerSize);
uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(new_sp);
- *stack_slot = address;
+ memcpy(stack_slot, &address, kPointerSize);
set_sp(new_sp);
return new_sp;
}
@@ -440,12 +442,6 @@
set_pc(start);
Run();
}
-
-
-void Simulator::CheckStackAlignment() {
- // TODO(aleram): The sp alignment check to perform depends on the
processor
- // state. Check the specifications for more details.
-}
// When the generated code calls an external reference we need to catch
that in
@@ -1721,11 +1717,6 @@
void Simulator::VisitDataProcessing2Source(Instruction* instr) {
- // TODO(mcapewel) move these to a higher level file, as they are global
- // assumptions.
- ASSERT((static_cast<int32_t>(-1) >> 1) == -1);
- ASSERT((static_cast<uint32_t>(-1) >> 1) == 0x7FFFFFFF);
-
Shift shift_op = NO_SHIFT;
int64_t result = 0;
switch (instr->Mask(DataProcessing2SourceMask)) {
@@ -3128,7 +3119,6 @@
} else if ((strcmp(cmd, "print") == 0) || (strcmp(cmd, "p") == 0)) {
if (argc == 2) {
if (strcmp(arg1, "all") == 0) {
- // TODO(all): better support for printing in the debugger.
PrintRegisters(true);
PrintFPRegisters(true);
} else {
=======================================
--- /branches/bleeding_edge/src/a64/stub-cache-a64.cc Mon Mar 17 15:43:33
2014 UTC
+++ /branches/bleeding_edge/src/a64/stub-cache-a64.cc Tue Mar 18 14:00:21
2014 UTC
@@ -929,16 +929,15 @@
Label miss;
Register reg = HandlerFrontendHeader(type, object_reg, holder, name,
&miss);
-
- // TODO(jbramely): HandlerFrontendHeader returns its result in
scratch1(), so
- // we can't use it below, but that isn't very obvious. Is there a better
way
- // of handling this?
+ // HandlerFrontendHeader can return its result into scratch1() so do not
+ // use it.
+ Register scratch2 = this->scratch2();
+ Register scratch3 = this->scratch3();
+ Register dictionary = this->scratch4();
+ ASSERT(!AreAliased(reg, scratch2, scratch3, dictionary));
if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
- ASSERT(!AreAliased(reg, scratch2(), scratch3(), scratch4()));
-
// Load the properties dictionary.
- Register dictionary = scratch4();
__ Ldr(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset));
// Probe the dictionary.
@@ -948,18 +947,18 @@
&probe_done,
dictionary,
this->name(),
- scratch2(),
- scratch3());
+ scratch2,
+ scratch3);
__ Bind(&probe_done);
// If probing finds an entry in the dictionary, scratch3 contains the
// pointer into the dictionary. Check that the value is the callback.
- Register pointer = scratch3();
+ Register pointer = scratch3;
const int kElementsStartOffset = NameDictionary::kHeaderSize +
NameDictionary::kElementsStartIndex * kPointerSize;
const int kValueOffset = kElementsStartOffset + kPointerSize;
- __ Ldr(scratch2(), FieldMemOperand(pointer, kValueOffset));
- __ Cmp(scratch2(), Operand(callback));
+ __ Ldr(scratch2, FieldMemOperand(pointer, kValueOffset));
+ __ Cmp(scratch2, Operand(callback));
__ B(ne, &miss);
}
@@ -1141,12 +1140,15 @@
void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
- Label success;
+ UseScratchRegisterScope temps(masm());
// Check that the object is a boolean.
- // TODO(all): Optimize this like LCodeGen::DoDeferredTaggedToI.
- __ JumpIfRoot(object, Heap::kTrueValueRootIndex, &success);
- __ JumpIfNotRoot(object, Heap::kFalseValueRootIndex, miss);
- __ Bind(&success);
+ Register true_root = temps.AcquireX();
+ Register false_root = temps.AcquireX();
+ ASSERT(!AreAliased(object, true_root, false_root));
+ __ LoadTrueFalseRoots(true_root, false_root);
+ __ Cmp(object, true_root);
+ __ Ccmp(object, false_root, ZFlag, ne);
+ __ B(ne, miss);
}
@@ -1162,12 +1164,12 @@
// Stub never generated for non-global objects that require access
checks.
ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
- // TODO(jbramley): Make Push take more than four arguments and combine
these
- // two calls.
- __ Push(receiver(), holder_reg);
+ // receiver() and holder_reg can alias.
+ ASSERT(!AreAliased(receiver(), scratch1(), scratch2(), value()));
+ ASSERT(!AreAliased(holder_reg, scratch1(), scratch2(), value()));
__ Mov(scratch1(), Operand(callback));
__ Mov(scratch2(), Operand(name));
- __ Push(scratch1(), scratch2(), value());
+ __ Push(receiver(), holder_reg, scratch1(), scratch2(), value());
// Do tail-call to the runtime system.
ExternalReference store_callback_property =
=======================================
--- /branches/bleeding_edge/src/a64/utils-a64.h Fri Mar 14 10:23:55 2014 UTC
+++ /branches/bleeding_edge/src/a64/utils-a64.h Tue Mar 18 14:00:21 2014 UTC
@@ -41,6 +41,10 @@
namespace v8 {
namespace internal {
+// These are global assumptions in v8.
+STATIC_ASSERT((static_cast<int32_t>(-1) >> 1) == -1);
+STATIC_ASSERT((static_cast<uint32_t>(-1) >> 1) == 0x7FFFFFFF);
+
// Floating point representation.
static inline uint32_t float_to_rawbits(float value) {
uint32_t bits = 0;
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.