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

Unified Diff: src/a64/code-stubs-a64.cc

Issue 155723005: A64: Synchronize with r19001. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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 | « include/v8.h ('k') | src/a64/full-codegen-a64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/a64/code-stubs-a64.cc
diff --git a/src/a64/code-stubs-a64.cc b/src/a64/code-stubs-a64.cc
index 315b6276c3ab34d666f34084c7546e53d93843f3..15a6d675f6380de5a0d03c9f54fe788b6e23b16a 100644
--- a/src/a64/code-stubs-a64.cc
+++ b/src/a64/code-stubs-a64.cc
@@ -186,20 +186,6 @@ void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
}
-void KeyedArrayCallStub::InitializeInterfaceDescriptor(
- Isolate* isolate,
- CodeStubInterfaceDescriptor* descriptor) {
- // x2: receiver
- static Register registers[] = { x2 };
- descriptor->register_param_count_ = sizeof(registers) / sizeof(registers[0]);
- descriptor->register_params_ = registers;
- descriptor->continuation_type_ = TAIL_CALL_CONTINUATION;
- descriptor->handler_arguments_mode_ = PASS_ARGUMENTS;
- descriptor->deoptimization_handler_ =
- FUNCTION_ADDR(KeyedCallIC_MissFromStubFailure);
-}
-
-
void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
@@ -497,6 +483,27 @@ void CallDescriptors::InitializeForIsolate(Isolate* isolate) {
descriptor->param_representations_ = representations;
descriptor->platform_specific_descriptor_ = &default_descriptor;
}
+ {
+ CallInterfaceDescriptor* descriptor =
+ isolate->call_descriptor(Isolate::ApiFunctionCall);
+ static Register registers[] = { x0, // callee
+ x4, // call_data
+ x2, // holder
+ x1, // api_function_address
+ cp, // context
+ };
+ static Representation representations[] = {
+ Representation::Tagged(), // callee
+ Representation::Tagged(), // call_data
+ Representation::Tagged(), // holder
+ Representation::External(), // api_function_address
+ Representation::Tagged(), // context
+ };
+ descriptor->register_param_count_ = 5;
+ descriptor->register_params_ = registers;
+ descriptor->param_representations_ = representations;
+ descriptor->platform_specific_descriptor_ = &default_descriptor;
+ }
}
@@ -3255,62 +3262,108 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
// x1 function the function to call
// x2 cache_cell cache cell for call target
Register function = x1;
- Register cache_cell = x2;
- Label slow, non_function;
+ Register type = x4;
+ Label slow, non_function, wrap, cont;
- // Check that the function is really a JavaScript function.
- __ JumpIfSmi(function, &non_function);
+ // TODO(jbramley): x2 is clobbered in a number of cases. Is it ever used?
- // Goto slow case if we do not have a function.
- __ JumpIfNotObjectType(function, x10, x10, JS_FUNCTION_TYPE, &slow);
+ // TODO(jbramley): This function has a lot of unnamed registers. Name them,
+ // and tidy things up a bit.
- if (RecordCallTarget()) {
- GenerateRecordCallTarget(masm);
+ if (NeedsChecks()) {
+ // Check that the function is really a JavaScript function.
+ __ JumpIfSmi(function, &non_function);
+
+ // Goto slow case if we do not have a function.
+ __ JumpIfNotObjectType(function, x10, x10, JS_FUNCTION_TYPE, &slow);
+
+ if (RecordCallTarget()) {
+ GenerateRecordCallTarget(masm);
+ }
}
// Fast-case: Invoke the function now.
// x1 function pushed function
ParameterCount actual(argc_);
+ if (CallAsMethod()) {
+ if (NeedsChecks()) {
+ // Do not transform the receiver for strict mode functions.
+ __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
+ __ Ldr(w3, FieldMemOperand(x2, SharedFunctionInfo::kCompilerHintsOffset));
+ __ Tbnz(w3, SharedFunctionInfo::kStrictModeFunction, &cont);
+
+ // Do not transform the receiver for native (Compilerhints already in x3).
+ __ Tbnz(w3, SharedFunctionInfo::kNative, &cont);
+ }
+
+ // Compute the receiver in non-strict mode.
+ __ Peek(x2, argc_ * kPointerSize);
+
+ if (NeedsChecks()) {
+ // x0: actual number of arguments
+ // x1: function
+ // x2: first argument
+ __ JumpIfSmi(x2, &wrap);
+ __ JumpIfObjectType(x2, x10, type, FIRST_SPEC_OBJECT_TYPE, &wrap, lt);
+ } else {
+ __ B(&wrap);
+ }
+
+ __ Bind(&cont);
+ }
__ InvokeFunction(function,
actual,
JUMP_FUNCTION,
NullCallWrapper());
- // Slow-case: Non-function called.
- __ Bind(&slow);
- if (RecordCallTarget()) {
- // If there is a call target cache, mark it megamorphic in the
- // non-function case. MegamorphicSentinel is an immortal immovable object
- // (undefined) so no write barrier is needed.
- ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()),
- masm->isolate()->heap()->undefined_value());
- __ LoadRoot(x11, Heap::kUndefinedValueRootIndex);
- __ Str(x11, FieldMemOperand(cache_cell, Cell::kValueOffset));
- }
- // Check for function proxy.
- // x10 : function type.
- __ Cmp(x10, JS_FUNCTION_PROXY_TYPE);
- __ B(ne, &non_function);
- __ Push(function); // put proxy as additional argument
- __ Mov(x0, argc_ + 1);
- __ Mov(x2, 0);
- __ GetBuiltinFunction(x1, Builtins::CALL_FUNCTION_PROXY);
- {
- Handle<Code> adaptor =
- masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
- __ Jump(adaptor, RelocInfo::CODE_TARGET);
+ if (NeedsChecks()) {
+ // Slow-case: Non-function called.
+ __ Bind(&slow);
+ if (RecordCallTarget()) {
+ // If there is a call target cache, mark it megamorphic in the
+ // non-function case. MegamorphicSentinel is an immortal immovable object
+ // (undefined) so no write barrier is needed.
+ ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()),
+ masm->isolate()->heap()->undefined_value());
+ __ LoadRoot(x11, Heap::kUndefinedValueRootIndex);
+ __ Str(x11, FieldMemOperand(x2, Cell::kValueOffset));
+ }
+ // Check for function proxy.
+ // x10 : function type.
+ __ CompareAndBranch(type, JS_FUNCTION_PROXY_TYPE, ne, &non_function);
+ __ Push(function); // put proxy as additional argument
+ __ Mov(x0, argc_ + 1);
+ __ Mov(x2, 0);
+ __ GetBuiltinFunction(x1, Builtins::CALL_FUNCTION_PROXY);
+ {
+ Handle<Code> adaptor =
+ masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
+ __ Jump(adaptor, RelocInfo::CODE_TARGET);
+ }
+
+ // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
+ // of the original receiver from the call site).
+ __ Bind(&non_function);
+ __ Poke(function, argc_ * kXRegSizeInBytes);
+ __ Mov(x0, argc_); // Set up the number of arguments.
+ __ Mov(x2, 0);
+ __ GetBuiltinFunction(function, Builtins::CALL_NON_FUNCTION);
+ __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+ RelocInfo::CODE_TARGET);
}
- // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
- // of the original receiver from the call site).
- __ Bind(&non_function);
- __ Poke(function, argc_ * kXRegSizeInBytes);
- __ Mov(x0, argc_); // Set up the number of arguments.
- __ Mov(x2, 0);
- __ GetBuiltinFunction(function, Builtins::CALL_NON_FUNCTION);
- __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
- RelocInfo::CODE_TARGET);
+ if (CallAsMethod()) {
+ __ Bind(&wrap);
+ // Wrap the receiver and patch it back onto the stack.
+ { FrameScope frame_scope(masm, StackFrame::INTERNAL);
+ __ Push(x1, x2);
+ __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
+ __ Pop(x1);
+ }
+ __ Poke(x0, argc_ * kPointerSize);
+ __ B(&cont);
+ }
}
@@ -4797,23 +4850,6 @@ void StubFailureTrampolineStub::Generate(MacroAssembler* masm) {
}
-void StubFailureTailCallTrampolineStub::Generate(MacroAssembler* masm) {
- CEntryStub ces(1, fp_registers_ ? kSaveFPRegs : kDontSaveFPRegs);
- __ Call(ces.GetCode(masm->isolate()), RelocInfo::CODE_TARGET);
- __ Mov(x1, x0);
- int parameter_count_offset =
- StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset;
- __ Ldr(x0, MemOperand(fp, parameter_count_offset));
- // The parameter count above includes the receiver for the arguments passed to
- // the deoptimization handler. Subtract the receiver for the parameter count
- // for the call.
- __ Sub(x0, x0, 1);
- masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE);
- ParameterCount argument_count(x0);
- __ InvokeFunction(x1, argument_count, JUMP_FUNCTION, NullCallWrapper());
-}
-
-
void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) {
if (masm->isolate()->function_entry_hook() != NULL) {
// TODO(all): This needs to be reliably consistent with
@@ -5499,10 +5535,9 @@ void InternalArrayConstructorStub::Generate(MacroAssembler* masm) {
void CallApiFunctionStub::Generate(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- x0 : callee
- // -- x1 : thunk_arg
- // -- x2 : holder
- // -- x3 : api_function_address
// -- x4 : call_data
+ // -- x2 : holder
+ // -- x1 : api_function_address
// -- cp : context
// --
// -- sp[0] : last argument
@@ -5512,10 +5547,9 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
// -----------------------------------
Register callee = x0;
- Register thunk_arg = x1;
- Register holder = x2;
- Register api_function_address = x3;
Register call_data = x4;
+ Register holder = x2;
+ Register api_function_address = x1;
Register context = cp;
int argc = ArgumentBits::decode(bit_field_);
@@ -5567,7 +5601,7 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
__ EnterExitFrame(false, x10, kApiStackSpace + kCallApiFunctionSpillSpace);
// TODO(all): Optimize this with stp and suchlike.
- ASSERT(!AreAliased(x0, thunk_arg, api_function_address));
+ ASSERT(!AreAliased(x0, api_function_address));
// x0 = FunctionCallbackInfo&
// Arguments is after the return address.
__ Add(x0, masm->StackPointer(), 1 * kPointerSize);
@@ -5598,7 +5632,6 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
const int spill_offset = 1 + kApiStackSpace;
__ CallApiFunctionAndReturn(api_function_address,
thunk_ref,
- thunk_arg,
kStackUnwindSpace,
spill_offset,
return_value_operand,
@@ -5607,6 +5640,52 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
}
+void CallApiGetterStub::Generate(MacroAssembler* masm) {
+ // ----------- S t a t e -------------
+ // -- sp[0] : name
+ // -- sp[8 - kArgsLength*8] : PropertyCallbackArguments object
+ // -- ...
+ // -- x2 : api_function_address
+ // -----------------------------------
+
+ Register api_function_address = x2;
+
+ __ Mov(x0, masm->StackPointer()); // x0 = Handle<Name>
+ __ Add(x1, x0, 1 * kPointerSize); // x1 = PCA
+
+ const int kApiStackSpace = 1;
+
+ // Allocate space for CallApiFunctionAndReturn can store some scratch
+ // registeres on the stack.
+ const int kCallApiFunctionSpillSpace = 4;
+
+ FrameScope frame_scope(masm, StackFrame::MANUAL);
+ __ EnterExitFrame(false, x10, kApiStackSpace + kCallApiFunctionSpillSpace);
+
+ // Create PropertyAccessorInfo instance on the stack above the exit frame with
+ // x1 (internal::Object** args_) as the data.
+ __ Poke(x1, 1 * kPointerSize);
+ __ Add(x1, masm->StackPointer(), 1 * kPointerSize); // x1 = AccessorInfo&
+
+ const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
+
+ Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
+ ExternalReference::Type thunk_type =
+ ExternalReference::PROFILING_GETTER_CALL;
+ ApiFunction thunk_fun(thunk_address);
+ ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
+ masm->isolate());
+
+ const int spill_offset = 1 + kApiStackSpace;
+ __ CallApiFunctionAndReturn(api_function_address,
+ thunk_ref,
+ kStackUnwindSpace,
+ spill_offset,
+ MemOperand(fp, 6 * kPointerSize),
+ NULL);
+}
+
+
#undef __
} } // namespace v8::internal
« no previous file with comments | « include/v8.h ('k') | src/a64/full-codegen-a64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698