#include "src/bootstrapper.h"
#include "src/code-stubs.h"
+#include "src/codegen.h"
+#include "src/ic/handler-compiler.h"
+#include "src/ic/ic.h"
+#include "src/isolate.h"
+#include "src/jsregexp.h"
#include "src/regexp-macro-assembler.h"
-#include "src/stub-cache.h"
+#include "src/runtime.h"
namespace v8 {
namespace internal {
-void FastNewClosureStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- // cp: context
- // x2: function info
- Register registers[] = { cp, x2 };
- descriptor->Initialize(
- MajorKey(), ARRAY_SIZE(registers), registers,
- Runtime::FunctionForId(Runtime::kNewClosureFromStubFailure)->entry);
-}
-
-
-void FastNewContextStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- // cp: context
- // x1: function
- Register registers[] = { cp, x1 };
- descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers);
-}
-
-
-void ToNumberStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- // cp: context
- // x0: value
- Register registers[] = { cp, x0 };
- descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers);
-}
-
-
-void NumberToStringStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- // cp: context
- // x0: value
- Register registers[] = { cp, x0 };
- descriptor->Initialize(
- MajorKey(), ARRAY_SIZE(registers), registers,
- Runtime::FunctionForId(Runtime::kNumberToStringRT)->entry);
-}
-
-
-void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- // cp: context
- // x3: array literals array
- // x2: array literal index
- // x1: constant elements
- Register registers[] = { cp, x3, x2, x1 };
- Representation representations[] = {
- Representation::Tagged(),
- Representation::Tagged(),
- Representation::Smi(),
- Representation::Tagged() };
- descriptor->Initialize(
- MajorKey(), ARRAY_SIZE(registers), registers,
- Runtime::FunctionForId(Runtime::kCreateArrayLiteralStubBailout)->entry,
- representations);
-}
-
-
-void FastCloneShallowObjectStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- // cp: context
- // x3: object literals array
- // x2: object literal index
- // x1: constant properties
- // x0: object literal flags
- Register registers[] = { cp, x3, x2, x1, x0 };
- descriptor->Initialize(
- MajorKey(), ARRAY_SIZE(registers), registers,
- Runtime::FunctionForId(Runtime::kCreateObjectLiteral)->entry);
-}
-
-
-void CreateAllocationSiteStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- // cp: context
- // x2: feedback vector
- // x3: call feedback slot
- Register registers[] = { cp, x2, x3 };
- descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers);
-}
-
-
-void CallFunctionStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- // x1 function the function to call
- Register registers[] = {cp, x1};
- descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers);
-}
-
-
-void CallConstructStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- // x0 : number of arguments
- // x1 : the function to call
- // x2 : feedback vector
- // x3 : slot in feedback vector (smi) (if r2 is not the megamorphic symbol)
- // TODO(turbofan): So far we don't gather type feedback and hence skip the
- // slot parameter, but ArrayConstructStub needs the vector to be undefined.
- Register registers[] = {cp, x0, x1, x2};
- descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers);
-}
-
-
-void RegExpConstructResultStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- // cp: context
- // x2: length
- // x1: index (of last match)
- // x0: string
- Register registers[] = { cp, x2, x1, x0 };
- descriptor->Initialize(
- MajorKey(), ARRAY_SIZE(registers), registers,
- Runtime::FunctionForId(Runtime::kRegExpConstructResult)->entry);
-}
-
-
-void TransitionElementsKindStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- // cp: context
- // x0: value (js_array)
- // x1: to_map
- Register registers[] = { cp, x0, x1 };
- Address entry =
- Runtime::FunctionForId(Runtime::kTransitionElementsKind)->entry;
- descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers,
- FUNCTION_ADDR(entry));
-}
-
-
-void CompareNilICStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- // cp: context
- // x0: value to compare
- Register registers[] = { cp, x0 };
- descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers,
- FUNCTION_ADDR(CompareNilIC_Miss));
- descriptor->SetMissHandler(
- ExternalReference(IC_Utility(IC::kCompareNilIC_Miss), isolate()));
-}
-
-
-const Register InterfaceDescriptor::ContextRegister() { return cp; }
-
static void InitializeArrayConstructorDescriptor(
- CodeStub::Major major, CodeStubInterfaceDescriptor* descriptor,
+ Isolate* isolate, CodeStubDescriptor* descriptor,
int constant_stack_parameter_count) {
// cp: context
// x1: function
Runtime::kArrayConstructor)->entry;
if (constant_stack_parameter_count == 0) {
- Register registers[] = { cp, x1, x2 };
- descriptor->Initialize(major, ARRAY_SIZE(registers), registers,
- deopt_handler, NULL, constant_stack_parameter_count,
+ descriptor->Initialize(deopt_handler, constant_stack_parameter_count,
JS_FUNCTION_STUB_MODE);
} else {
- // stack param count needs (constructor pointer, and single argument)
- Register registers[] = { cp, x1, x2, x0 };
- Representation representations[] = {
- Representation::Tagged(),
- Representation::Tagged(),
- Representation::Tagged(),
- Representation::Integer32() };
- descriptor->Initialize(major, ARRAY_SIZE(registers), registers, x0,
- deopt_handler, representations,
- constant_stack_parameter_count,
+ descriptor->Initialize(x0, deopt_handler, constant_stack_parameter_count,
JS_FUNCTION_STUB_MODE, PASS_ARGUMENTS);
}
}
-void ArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- InitializeArrayConstructorDescriptor(MajorKey(), descriptor, 0);
+void ArrayNoArgumentConstructorStub::InitializeDescriptor(
+ CodeStubDescriptor* descriptor) {
+ InitializeArrayConstructorDescriptor(isolate(), descriptor, 0);
}
-void ArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- InitializeArrayConstructorDescriptor(MajorKey(), descriptor, 1);
+void ArraySingleArgumentConstructorStub::InitializeDescriptor(
+ CodeStubDescriptor* descriptor) {
+ InitializeArrayConstructorDescriptor(isolate(), descriptor, 1);
}
-void ArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- InitializeArrayConstructorDescriptor(MajorKey(), descriptor, -1);
+void ArrayNArgumentsConstructorStub::InitializeDescriptor(
+ CodeStubDescriptor* descriptor) {
+ InitializeArrayConstructorDescriptor(isolate(), descriptor, -1);
}
static void InitializeInternalArrayConstructorDescriptor(
- CodeStub::Major major, CodeStubInterfaceDescriptor* descriptor,
+ Isolate* isolate, CodeStubDescriptor* descriptor,
int constant_stack_parameter_count) {
- // cp: context
- // x1: constructor function
- // x0: number of arguments to the constructor function
Address deopt_handler = Runtime::FunctionForId(
Runtime::kInternalArrayConstructor)->entry;
if (constant_stack_parameter_count == 0) {
- Register registers[] = { cp, x1 };
- descriptor->Initialize(major, ARRAY_SIZE(registers), registers,
- deopt_handler, NULL, constant_stack_parameter_count,
+ descriptor->Initialize(deopt_handler, constant_stack_parameter_count,
JS_FUNCTION_STUB_MODE);
} else {
- // stack param count needs (constructor pointer, and single argument)
- Register registers[] = { cp, x1, x0 };
- Representation representations[] = {
- Representation::Tagged(),
- Representation::Tagged(),
- Representation::Integer32() };
- descriptor->Initialize(major, ARRAY_SIZE(registers), registers, x0,
- deopt_handler, representations,
- constant_stack_parameter_count,
+ descriptor->Initialize(x0, deopt_handler, constant_stack_parameter_count,
JS_FUNCTION_STUB_MODE, PASS_ARGUMENTS);
}
}
-void InternalArrayNoArgumentConstructorStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- InitializeInternalArrayConstructorDescriptor(MajorKey(), descriptor, 0);
+void InternalArrayNoArgumentConstructorStub::InitializeDescriptor(
+ CodeStubDescriptor* descriptor) {
+ InitializeInternalArrayConstructorDescriptor(isolate(), descriptor, 0);
}
-void InternalArraySingleArgumentConstructorStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- InitializeInternalArrayConstructorDescriptor(MajorKey(), descriptor, 1);
+void InternalArraySingleArgumentConstructorStub::InitializeDescriptor(
+ CodeStubDescriptor* descriptor) {
+ InitializeInternalArrayConstructorDescriptor(isolate(), descriptor, 1);
}
-void InternalArrayNArgumentsConstructorStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- InitializeInternalArrayConstructorDescriptor(MajorKey(), descriptor, -1);
-}
-
-
-void ToBooleanStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- // cp: context
- // x0: value
- Register registers[] = { cp, x0 };
- descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers,
- FUNCTION_ADDR(ToBooleanIC_Miss));
- descriptor->SetMissHandler(
- ExternalReference(IC_Utility(IC::kToBooleanIC_Miss), isolate()));
-}
-
-
-void BinaryOpICStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- // cp: context
- // x1: left operand
- // x0: right operand
- Register registers[] = { cp, x1, x0 };
- descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers,
- FUNCTION_ADDR(BinaryOpIC_Miss));
- descriptor->SetMissHandler(
- ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate()));
-}
-
-
-void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- // cp: context
- // x2: allocation site
- // x1: left operand
- // x0: right operand
- Register registers[] = { cp, x2, x1, x0 };
- descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers,
- FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite));
-}
-
-
-void StringAddStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- // cp: context
- // x1: left operand
- // x0: right operand
- Register registers[] = { cp, x1, x0 };
- descriptor->Initialize(MajorKey(), ARRAY_SIZE(registers), registers,
- Runtime::FunctionForId(Runtime::kStringAdd)->entry);
-}
-
-
-void CallDescriptors::InitializeForIsolate(Isolate* isolate) {
- static PlatformInterfaceDescriptor default_descriptor =
- PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
-
- static PlatformInterfaceDescriptor noInlineDescriptor =
- PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS);
-
- {
- CallInterfaceDescriptor* descriptor =
- isolate->call_descriptor(Isolate::ArgumentAdaptorCall);
- Register registers[] = { cp, // context
- x1, // JSFunction
- x0, // actual number of arguments
- x2, // expected number of arguments
- };
- Representation representations[] = {
- Representation::Tagged(), // context
- Representation::Tagged(), // JSFunction
- Representation::Integer32(), // actual number of arguments
- Representation::Integer32(), // expected number of arguments
- };
- descriptor->Initialize(ARRAY_SIZE(registers), registers,
- representations, &default_descriptor);
- }
- {
- CallInterfaceDescriptor* descriptor =
- isolate->call_descriptor(Isolate::KeyedCall);
- Register registers[] = { cp, // context
- x2, // key
- };
- Representation representations[] = {
- Representation::Tagged(), // context
- Representation::Tagged(), // key
- };
- descriptor->Initialize(ARRAY_SIZE(registers), registers,
- representations, &noInlineDescriptor);
- }
- {
- CallInterfaceDescriptor* descriptor =
- isolate->call_descriptor(Isolate::NamedCall);
- Register registers[] = { cp, // context
- x2, // name
- };
- Representation representations[] = {
- Representation::Tagged(), // context
- Representation::Tagged(), // name
- };
- descriptor->Initialize(ARRAY_SIZE(registers), registers,
- representations, &noInlineDescriptor);
- }
- {
- CallInterfaceDescriptor* descriptor =
- isolate->call_descriptor(Isolate::CallHandler);
- Register registers[] = { cp, // context
- x0, // receiver
- };
- Representation representations[] = {
- Representation::Tagged(), // context
- Representation::Tagged(), // receiver
- };
- descriptor->Initialize(ARRAY_SIZE(registers), registers,
- representations, &default_descriptor);
- }
- {
- CallInterfaceDescriptor* descriptor =
- isolate->call_descriptor(Isolate::ApiFunctionCall);
- Register registers[] = { cp, // context
- x0, // callee
- x4, // call_data
- x2, // holder
- x1, // api_function_address
- };
- Representation representations[] = {
- Representation::Tagged(), // context
- Representation::Tagged(), // callee
- Representation::Tagged(), // call_data
- Representation::Tagged(), // holder
- Representation::External(), // api_function_address
- };
- descriptor->Initialize(ARRAY_SIZE(registers), registers,
- representations, &default_descriptor);
- }
+void InternalArrayNArgumentsConstructorStub::InitializeDescriptor(
+ CodeStubDescriptor* descriptor) {
+ InitializeInternalArrayConstructorDescriptor(isolate(), descriptor, -1);
}
#define __ ACCESS_MASM(masm)
-void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
+void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm,
+ ExternalReference miss) {
// Update the static counter each time a new code stub is generated.
isolate()->counters()->code_stubs()->Increment();
- CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor();
- int param_count = descriptor->GetEnvironmentParameterCount();
+ CallInterfaceDescriptor descriptor = GetCallInterfaceDescriptor();
+ int param_count = descriptor.GetEnvironmentParameterCount();
{
// Call the runtime system in a fresh internal frame.
FrameScope scope(masm, StackFrame::INTERNAL);
DCHECK((param_count == 0) ||
- x0.Is(descriptor->GetEnvironmentParameterRegister(param_count - 1)));
+ x0.Is(descriptor.GetEnvironmentParameterRegister(param_count - 1)));
// Push arguments
MacroAssembler::PushPopQueue queue(masm);
for (int i = 0; i < param_count; ++i) {
- queue.Queue(descriptor->GetEnvironmentParameterRegister(i));
+ queue.Queue(descriptor.GetEnvironmentParameterRegister(i));
}
queue.PushQueued();
- ExternalReference miss = descriptor->miss_handler();
__ CallExternalReference(miss, param_count);
}
if ((cond == lt) || (cond == gt)) {
__ JumpIfObjectType(right, scratch, scratch, FIRST_SPEC_OBJECT_TYPE, slow,
ge);
+ } else if (cond == eq) {
+ __ JumpIfHeapNumber(right, &heap_number);
} else {
Register right_type = scratch;
__ JumpIfObjectType(right, right_type, right_type, HEAP_NUMBER_TYPE,
&heap_number);
// Comparing JS objects with <=, >= is complicated.
- if (cond != eq) {
- __ Cmp(right_type, FIRST_SPEC_OBJECT_TYPE);
- __ B(ge, slow);
- // Normally here we fall through to return_equal, but undefined is
- // special: (undefined == undefined) == true, but
- // (undefined <= undefined) == false! See ECMAScript 11.8.5.
- if ((cond == le) || (cond == ge)) {
- __ Cmp(right_type, ODDBALL_TYPE);
- __ B(ne, &return_equal);
- __ JumpIfNotRoot(right, Heap::kUndefinedValueRootIndex, &return_equal);
- if (cond == le) {
- // undefined <= undefined should fail.
- __ Mov(result, GREATER);
- } else {
- // undefined >= undefined should fail.
- __ Mov(result, LESS);
- }
- __ Ret();
+ __ Cmp(right_type, FIRST_SPEC_OBJECT_TYPE);
+ __ B(ge, slow);
+ // Normally here we fall through to return_equal, but undefined is
+ // special: (undefined == undefined) == true, but
+ // (undefined <= undefined) == false! See ECMAScript 11.8.5.
+ if ((cond == le) || (cond == ge)) {
+ __ Cmp(right_type, ODDBALL_TYPE);
+ __ B(ne, &return_equal);
+ __ JumpIfNotRoot(right, Heap::kUndefinedValueRootIndex, &return_equal);
+ if (cond == le) {
+ // undefined <= undefined should fail.
+ __ Mov(result, GREATER);
+ } else {
+ // undefined >= undefined should fail.
+ __ Mov(result, LESS);
}
+ __ Ret();
}
}
Register right,
FPRegister left_d,
FPRegister right_d,
- Register scratch,
Label* slow,
bool strict) {
- DCHECK(!AreAliased(left, right, scratch));
DCHECK(!AreAliased(left_d, right_d));
DCHECK((left.is(x0) && right.is(x1)) ||
(right.is(x0) && left.is(x1)));
// If right is not a number and left is a smi, then strict equality cannot
// succeed. Return non-equal.
Label is_heap_number;
- __ JumpIfObjectType(right, scratch, scratch, HEAP_NUMBER_TYPE,
- &is_heap_number);
+ __ JumpIfHeapNumber(right, &is_heap_number);
// Register right is a non-zero pointer, which is a valid NOT_EQUAL result.
if (!right.is(result)) {
__ Mov(result, NOT_EQUAL);
} else {
// Smi compared non-strictly with a non-smi, non-heap-number. Call the
// runtime.
- __ JumpIfNotObjectType(right, scratch, scratch, HEAP_NUMBER_TYPE, slow);
+ __ JumpIfNotHeapNumber(right, slow);
}
// Left is the smi. Right is a heap number. Load right value into right_d, and
// If left is not a number and right is a smi then strict equality cannot
// succeed. Return non-equal.
Label is_heap_number;
- __ JumpIfObjectType(left, scratch, scratch, HEAP_NUMBER_TYPE,
- &is_heap_number);
+ __ JumpIfHeapNumber(left, &is_heap_number);
// Register left is a non-zero pointer, which is a valid NOT_EQUAL result.
if (!left.is(result)) {
__ Mov(result, NOT_EQUAL);
} else {
// Smi compared non-strictly with a non-smi, non-heap-number. Call the
// runtime.
- __ JumpIfNotObjectType(left, scratch, scratch, HEAP_NUMBER_TYPE, slow);
+ __ JumpIfNotHeapNumber(left, slow);
}
// Right is the smi. Left is a heap number. Load left value into left_d, and
}
-static void ICCompareStub_CheckInputType(MacroAssembler* masm,
- Register input,
- Register scratch,
- CompareIC::State expected,
+static void CompareICStub_CheckInputType(MacroAssembler* masm, Register input,
+ CompareICState::State expected,
Label* fail) {
Label ok;
- if (expected == CompareIC::SMI) {
+ if (expected == CompareICState::SMI) {
__ JumpIfNotSmi(input, fail);
- } else if (expected == CompareIC::NUMBER) {
+ } else if (expected == CompareICState::NUMBER) {
__ JumpIfSmi(input, &ok);
- __ CheckMap(input, scratch, Heap::kHeapNumberMapRootIndex, fail,
- DONT_DO_SMI_CHECK);
+ __ JumpIfNotHeapNumber(input, fail);
}
// We could be strict about internalized/non-internalized here, but as long as
// hydrogen doesn't care, the stub doesn't have to care either.
}
-void ICCompareStub::GenerateGeneric(MacroAssembler* masm) {
+void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
Register lhs = x1;
Register rhs = x0;
Register result = x0;
Condition cond = GetCondition();
Label miss;
- ICCompareStub_CheckInputType(masm, lhs, x2, left_, &miss);
- ICCompareStub_CheckInputType(masm, rhs, x3, right_, &miss);
+ CompareICStub_CheckInputType(masm, lhs, left(), &miss);
+ CompareICStub_CheckInputType(masm, rhs, right(), &miss);
Label slow; // Call builtin.
Label not_smis, both_loaded_as_doubles;
// rhs_d, left into lhs_d.
FPRegister rhs_d = d0;
FPRegister lhs_d = d1;
- EmitSmiNonsmiComparison(masm, lhs, rhs, lhs_d, rhs_d, x10, &slow, strict());
+ EmitSmiNonsmiComparison(masm, lhs, rhs, lhs_d, rhs_d, &slow, strict());
__ Bind(&both_loaded_as_doubles);
// The arguments have been converted to doubles and stored in rhs_d and
&flat_string_check, &slow);
}
- // Check for both being sequential ASCII strings, and inline if that is the
- // case.
+ // Check for both being sequential one-byte strings,
+ // and inline if that is the case.
__ Bind(&flat_string_check);
- __ JumpIfBothInstanceTypesAreNotSequentialAscii(lhs_type, rhs_type, x14,
- x15, &slow);
+ __ JumpIfBothInstanceTypesAreNotSequentialOneByte(lhs_type, rhs_type, x14,
+ x15, &slow);
__ IncrementCounter(isolate()->counters()->string_compare_native(), 1, x10,
x11);
if (cond == eq) {
- StringCompareStub::GenerateFlatAsciiStringEquals(masm, lhs, rhs,
- x10, x11, x12);
+ StringHelper::GenerateFlatOneByteStringEquals(masm, lhs, rhs, x10, x11,
+ x12);
} else {
- StringCompareStub::GenerateCompareFlatAsciiStrings(masm, lhs, rhs,
- x10, x11, x12, x13);
+ StringHelper::GenerateCompareFlatOneByteStrings(masm, lhs, rhs, x10, x11,
+ x12, x13);
}
// Never fall through to here.
saved_fp_regs.Remove(*(masm->FPTmpList()));
__ PushCPURegList(saved_regs);
- if (save_doubles_ == kSaveFPRegs) {
+ if (save_doubles()) {
__ PushCPURegList(saved_fp_regs);
}
__ CallCFunction(
ExternalReference::store_buffer_overflow_function(isolate()), 1, 0);
- if (save_doubles_ == kSaveFPRegs) {
+ if (save_doubles()) {
__ PopCPURegList(saved_fp_regs);
}
__ PopCPURegList(saved_regs);
Register result_tagged = x0;
Register base_tagged = x10;
- Register exponent_tagged = x11;
- Register exponent_integer = x12;
+ Register exponent_tagged = MathPowTaggedDescriptor::exponent();
+ DCHECK(exponent_tagged.is(x11));
+ Register exponent_integer = MathPowIntegerDescriptor::exponent();
+ DCHECK(exponent_integer.is(x12));
Register scratch1 = x14;
Register scratch0 = x15;
Register saved_lr = x19;
Label done;
// Unpack the inputs.
- if (exponent_type_ == ON_STACK) {
+ if (exponent_type() == ON_STACK) {
Label base_is_smi;
Label unpack_exponent;
// exponent_tagged is a heap number, so load its double value.
__ Ldr(exponent_double,
FieldMemOperand(exponent_tagged, HeapNumber::kValueOffset));
- } else if (exponent_type_ == TAGGED) {
+ } else if (exponent_type() == TAGGED) {
__ JumpIfSmi(exponent_tagged, &exponent_is_smi);
__ Ldr(exponent_double,
FieldMemOperand(exponent_tagged, HeapNumber::kValueOffset));
}
// Handle double (heap number) exponents.
- if (exponent_type_ != INTEGER) {
+ if (exponent_type() != INTEGER) {
// Detect integer exponents stored as doubles and handle those in the
// integer fast-path.
__ TryRepresentDoubleAsInt64(exponent_integer, exponent_double,
scratch0_double, &exponent_is_integer);
- if (exponent_type_ == ON_STACK) {
+ if (exponent_type() == ON_STACK) {
FPRegister half_double = d3;
FPRegister minus_half_double = d4;
// Detect square root case. Crankshaft detects constant +/-0.5 at compile
__ Fcmp(result_double, 0.0);
__ B(&done, ne);
- if (exponent_type_ == ON_STACK) {
+ if (exponent_type() == ON_STACK) {
// Bail out to runtime code.
__ Bind(&call_runtime);
// Put the arguments back on the stack.
// Enter the exit frame. Reserve three slots to preserve x21-x23 callee-saved
// registers.
FrameScope scope(masm, StackFrame::MANUAL);
- __ EnterExitFrame(save_doubles_, x10, 3);
+ __ EnterExitFrame(save_doubles(), x10, 3);
DCHECK(csp.Is(__ StackPointer()));
// Poke callee-saved registers into reserved space.
__ Peek(argc, 2 * kPointerSize);
__ Peek(target, 3 * kPointerSize);
- __ LeaveExitFrame(save_doubles_, x10, true);
+ __ LeaveExitFrame(save_doubles(), x10, true);
DCHECK(jssp.Is(__ StackPointer()));
// Pop or drop the remaining stack slots and return from the stub.
// jssp[24]: Arguments array (of size argc), including receiver.
// x4: argv.
// Output:
// x0: result.
-void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
+void JSEntryStub::Generate(MacroAssembler* masm) {
DCHECK(jssp.Is(__ StackPointer()));
Register code_entry = x0;
__ Fmov(fp_zero, 0.0);
// Build an entry frame (see layout below).
- int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY;
+ int marker = type();
int64_t bad_frame_pointer = -1L; // Bad frame pointer to fail if it is used.
__ Mov(x13, bad_frame_pointer);
__ Mov(x12, Smi::FromInt(marker));
// x2: receiver.
// x3: argc.
// x4: argv.
- ExternalReference entry(is_construct ? Builtins::kJSConstructEntryTrampoline
- : Builtins::kJSEntryTrampoline,
+ ExternalReference entry(type() == StackFrame::ENTRY_CONSTRUCT
+ ? Builtins::kJSConstructEntryTrampoline
+ : Builtins::kJSEntryTrampoline,
isolate());
__ Mov(x10, entry);
void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
Label miss;
- Register receiver = LoadIC::ReceiverRegister();
+ Register receiver = LoadDescriptor::ReceiverRegister();
NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, x10,
x11, &miss);
}
-Register InstanceofStub::left() {
- // Object to check (instanceof lhs).
- return x11;
-}
-
-
-Register InstanceofStub::right() {
- // Constructor function (instanceof rhs).
- return x10;
-}
-
-
void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
- Register arg_count = x0;
- Register key = x1;
+ Register arg_count = ArgumentsAccessReadDescriptor::parameter_count();
+ Register key = ArgumentsAccessReadDescriptor::index();
+ DCHECK(arg_count.is(x0));
+ DCHECK(key.is(x1));
// The displacement is the offset of the last parameter (if any) relative
// to the frame pointer.
}
+void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) {
+ // Return address is in lr.
+ Label slow;
+
+ Register receiver = LoadDescriptor::ReceiverRegister();
+ Register key = LoadDescriptor::NameRegister();
+
+ // Check that the key is an array index, that is Uint32.
+ __ TestAndBranchIfAnySet(key, kSmiTagMask | kSmiSignMask, &slow);
+
+ // Everything is fine, call runtime.
+ __ Push(receiver, key);
+ __ TailCallExternalReference(
+ ExternalReference(IC_Utility(IC::kLoadElementWithInterceptor),
+ masm->isolate()),
+ 2, 1);
+
+ __ Bind(&slow);
+ PropertyAccessCompiler::TailCallBuiltin(
+ masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
+}
+
+
void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
// Stack layout on entry.
// jssp[0]: number of parameters (tagged)
// w0 string_type type of subject string
// x2 jsstring_length subject string length
// x3 jsregexp_object JSRegExp object
- // w4 string_encoding ASCII or UC16
+ // w4 string_encoding Latin1 or UC16
// w5 sliced_string_offset if the string is a SlicedString
// offset to the underlying string
// w6 string_representation groups attributes of the string:
STATIC_ASSERT(kStringEncodingMask == 0x04);
// Find the code object based on the assumptions above.
- // kDataAsciiCodeOffset and kDataUC16CodeOffset are adjacent, adds an offset
+ // kDataOneByteCodeOffset and kDataUC16CodeOffset are adjacent, adds an offset
// of kPointerSize to reach the latter.
- DCHECK_EQ(JSRegExp::kDataAsciiCodeOffset + kPointerSize,
+ DCHECK_EQ(JSRegExp::kDataOneByteCodeOffset + kPointerSize,
JSRegExp::kDataUC16CodeOffset);
__ Mov(x10, kPointerSize);
- // We will need the encoding later: ASCII = 0x04
- // UC16 = 0x00
+ // We will need the encoding later: Latin1 = 0x04
+ // UC16 = 0x00
__ Ands(string_encoding, string_type, kStringEncodingMask);
__ CzeroX(x10, ne);
__ Add(x10, regexp_data, x10);
- __ Ldr(code_object, FieldMemOperand(x10, JSRegExp::kDataAsciiCodeOffset));
+ __ Ldr(code_object, FieldMemOperand(x10, JSRegExp::kDataOneByteCodeOffset));
// (E) Carry on. String handling is done.
__ Ldr(length, UntagSmiFieldMemOperand(subject, String::kLengthOffset));
// Handle UC16 encoding, two bytes make one character.
- // string_encoding: if ASCII: 0x04
- // if UC16: 0x00
+ // string_encoding: if Latin1: 0x04
+ // if UC16: 0x00
STATIC_ASSERT(kStringEncodingMask == 0x04);
__ Ubfx(string_encoding, string_encoding, 2, 1);
__ Eor(string_encoding, string_encoding, 1);
- // string_encoding: if ASCII: 0
- // if UC16: 1
+ // string_encoding: if Latin1: 0
+ // if UC16: 1
// Convert string positions from characters to bytes.
// Previous index is in x1.
// index : slot in feedback vector (smi)
Label initialize, done, miss, megamorphic, not_array_function;
- DCHECK_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()),
+ DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()),
masm->isolate()->heap()->megamorphic_symbol());
- DCHECK_EQ(*TypeFeedbackInfo::UninitializedSentinel(masm->isolate()),
+ DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()),
masm->isolate()->heap()->uninitialized_symbol());
// Load the cache state.
void CallFunctionStub::Generate(MacroAssembler* masm) {
ASM_LOCATION("CallFunctionStub::Generate");
- CallFunctionNoFeedback(masm, argc_, NeedsChecks(), CallAsMethod());
+ CallFunctionNoFeedback(masm, argc(), NeedsChecks(), CallAsMethod());
}
__ TailCallStub(&stub);
__ bind(&miss);
- GenerateMiss(masm, IC::kCallIC_Customization_Miss);
+ GenerateMiss(masm);
// The slow case, we need this no matter what to complete a call after a miss.
CallFunctionNoFeedback(masm,
Label extra_checks_or_miss, slow_start;
Label slow, non_function, wrap, cont;
Label have_js_function;
- int argc = state_.arg_count();
+ int argc = arg_count();
ParameterCount actual(argc);
Register function = x1;
__ B(ne, &extra_checks_or_miss);
__ bind(&have_js_function);
- if (state_.CallAsMethod()) {
+ if (CallAsMethod()) {
EmitContinueIfStrictOrNative(masm, &cont);
// Compute the receiver in sloppy mode.
__ bind(&slow);
EmitSlowCase(masm, argc, function, type, &non_function);
- if (state_.CallAsMethod()) {
+ if (CallAsMethod()) {
__ bind(&wrap);
EmitWrapCase(masm, argc, &cont);
}
// We are here because tracing is on or we are going monomorphic.
__ bind(&miss);
- GenerateMiss(masm, IC::kCallIC_Miss);
+ GenerateMiss(masm);
// the slow case
__ bind(&slow_start);
}
-void CallICStub::GenerateMiss(MacroAssembler* masm, IC::UtilityId id) {
+void CallICStub::GenerateMiss(MacroAssembler* masm) {
ASM_LOCATION("CallICStub[Miss]");
// Get the receiver of the function from the stack; 1 ~ return address.
- __ Peek(x4, (state_.arg_count() + 1) * kPointerSize);
+ __ Peek(x4, (arg_count() + 1) * kPointerSize);
{
FrameScope scope(masm, StackFrame::INTERNAL);
__ Push(x4, x1, x2, x3);
// Call the entry.
+ IC::UtilityId id = GetICState() == DEFAULT ? IC::kCallIC_Miss
+ : IC::kCallIC_Customization_Miss;
+
ExternalReference miss = ExternalReference(IC_Utility(id),
masm->isolate());
__ CallExternalReference(miss, 4);
__ Bind(&index_not_smi_);
// If index is a heap number, try converting it to an integer.
- __ CheckMap(index_,
- result_,
- Heap::kHeapNumberMapRootIndex,
- index_not_number_,
- DONT_DO_SMI_CHECK);
+ __ JumpIfNotHeapNumber(index_, index_not_number_);
call_helper.BeforeCall(masm);
// Save object_ on the stack and pass index_ as argument for runtime call.
__ Push(object_, index_);
__ B(hi, &slow_case_);
__ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex);
- // At this point code register contains smi tagged ASCII char code.
+ // At this point code register contains smi tagged one-byte char code.
__ Add(result_, result_, Operand::UntagSmiAndScale(code_, kPointerSizeLog2));
__ Ldr(result_, FieldMemOperand(result_, FixedArray::kHeaderSize));
__ JumpIfRoot(result_, Heap::kUndefinedValueRootIndex, &slow_case_);
}
-void ICCompareStub::GenerateSmis(MacroAssembler* masm) {
+void CompareICStub::GenerateSmis(MacroAssembler* masm) {
// Inputs are in x0 (lhs) and x1 (rhs).
- DCHECK(state_ == CompareIC::SMI);
- ASM_LOCATION("ICCompareStub[Smis]");
+ DCHECK(state() == CompareICState::SMI);
+ ASM_LOCATION("CompareICStub[Smis]");
Label miss;
// Bail out (to 'miss') unless both x0 and x1 are smis.
__ JumpIfEitherNotSmi(x0, x1, &miss);
}
-void ICCompareStub::GenerateNumbers(MacroAssembler* masm) {
- DCHECK(state_ == CompareIC::NUMBER);
- ASM_LOCATION("ICCompareStub[HeapNumbers]");
+void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
+ DCHECK(state() == CompareICState::NUMBER);
+ ASM_LOCATION("CompareICStub[HeapNumbers]");
Label unordered, maybe_undefined1, maybe_undefined2;
Label miss, handle_lhs, values_in_d_regs;
FPRegister rhs_d = d0;
FPRegister lhs_d = d1;
- if (left_ == CompareIC::SMI) {
+ if (left() == CompareICState::SMI) {
__ JumpIfNotSmi(lhs, &miss);
}
- if (right_ == CompareIC::SMI) {
+ if (right() == CompareICState::SMI) {
__ JumpIfNotSmi(rhs, &miss);
}
// Load rhs if it's a heap number.
__ JumpIfSmi(rhs, &handle_lhs);
- __ CheckMap(rhs, x10, Heap::kHeapNumberMapRootIndex, &maybe_undefined1,
- DONT_DO_SMI_CHECK);
+ __ JumpIfNotHeapNumber(rhs, &maybe_undefined1);
__ Ldr(rhs_d, FieldMemOperand(rhs, HeapNumber::kValueOffset));
// Load lhs if it's a heap number.
__ Bind(&handle_lhs);
__ JumpIfSmi(lhs, &values_in_d_regs);
- __ CheckMap(lhs, x10, Heap::kHeapNumberMapRootIndex, &maybe_undefined2,
- DONT_DO_SMI_CHECK);
+ __ JumpIfNotHeapNumber(lhs, &maybe_undefined2);
__ Ldr(lhs_d, FieldMemOperand(lhs, HeapNumber::kValueOffset));
__ Bind(&values_in_d_regs);
__ Ret();
__ Bind(&unordered);
- ICCompareStub stub(isolate(), op_, CompareIC::GENERIC, CompareIC::GENERIC,
- CompareIC::GENERIC);
+ CompareICStub stub(isolate(), op(), CompareICState::GENERIC,
+ CompareICState::GENERIC, CompareICState::GENERIC);
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
__ Bind(&maybe_undefined1);
- if (Token::IsOrderedRelationalCompareOp(op_)) {
+ if (Token::IsOrderedRelationalCompareOp(op())) {
__ JumpIfNotRoot(rhs, Heap::kUndefinedValueRootIndex, &miss);
__ JumpIfSmi(lhs, &unordered);
- __ JumpIfNotObjectType(lhs, x10, x10, HEAP_NUMBER_TYPE, &maybe_undefined2);
+ __ JumpIfNotHeapNumber(lhs, &maybe_undefined2);
__ B(&unordered);
}
__ Bind(&maybe_undefined2);
- if (Token::IsOrderedRelationalCompareOp(op_)) {
+ if (Token::IsOrderedRelationalCompareOp(op())) {
__ JumpIfRoot(lhs, Heap::kUndefinedValueRootIndex, &unordered);
}
}
-void ICCompareStub::GenerateInternalizedStrings(MacroAssembler* masm) {
- DCHECK(state_ == CompareIC::INTERNALIZED_STRING);
- ASM_LOCATION("ICCompareStub[InternalizedStrings]");
+void CompareICStub::GenerateInternalizedStrings(MacroAssembler* masm) {
+ DCHECK(state() == CompareICState::INTERNALIZED_STRING);
+ ASM_LOCATION("CompareICStub[InternalizedStrings]");
Label miss;
Register result = x0;
}
-void ICCompareStub::GenerateUniqueNames(MacroAssembler* masm) {
- DCHECK(state_ == CompareIC::UNIQUE_NAME);
- ASM_LOCATION("ICCompareStub[UniqueNames]");
+void CompareICStub::GenerateUniqueNames(MacroAssembler* masm) {
+ DCHECK(state() == CompareICState::UNIQUE_NAME);
+ ASM_LOCATION("CompareICStub[UniqueNames]");
DCHECK(GetCondition() == eq);
Label miss;
// To avoid a miss, each instance type should be either SYMBOL_TYPE or it
// should have kInternalizedTag set.
- __ JumpIfNotUniqueName(lhs_instance_type, &miss);
- __ JumpIfNotUniqueName(rhs_instance_type, &miss);
+ __ JumpIfNotUniqueNameInstanceType(lhs_instance_type, &miss);
+ __ JumpIfNotUniqueNameInstanceType(rhs_instance_type, &miss);
// Unique names are compared by identity.
STATIC_ASSERT(EQUAL == 0);
}
-void ICCompareStub::GenerateStrings(MacroAssembler* masm) {
- DCHECK(state_ == CompareIC::STRING);
- ASM_LOCATION("ICCompareStub[Strings]");
+void CompareICStub::GenerateStrings(MacroAssembler* masm) {
+ DCHECK(state() == CompareICState::STRING);
+ ASM_LOCATION("CompareICStub[Strings]");
Label miss;
- bool equality = Token::IsEqualityOp(op_);
+ bool equality = Token::IsEqualityOp(op());
Register result = x0;
Register rhs = x0;
__ Bind(¬_internalized_strings);
}
- // Check that both strings are sequential ASCII.
+ // Check that both strings are sequential one-byte.
Label runtime;
- __ JumpIfBothInstanceTypesAreNotSequentialAscii(
- lhs_type, rhs_type, x12, x13, &runtime);
+ __ JumpIfBothInstanceTypesAreNotSequentialOneByte(lhs_type, rhs_type, x12,
+ x13, &runtime);
- // Compare flat ASCII strings. Returns when done.
+ // Compare flat one-byte strings. Returns when done.
if (equality) {
- StringCompareStub::GenerateFlatAsciiStringEquals(
- masm, lhs, rhs, x10, x11, x12);
+ StringHelper::GenerateFlatOneByteStringEquals(masm, lhs, rhs, x10, x11,
+ x12);
} else {
- StringCompareStub::GenerateCompareFlatAsciiStrings(
- masm, lhs, rhs, x10, x11, x12, x13);
+ StringHelper::GenerateCompareFlatOneByteStrings(masm, lhs, rhs, x10, x11,
+ x12, x13);
}
// Handle more complex cases in runtime.
}
-void ICCompareStub::GenerateObjects(MacroAssembler* masm) {
- DCHECK(state_ == CompareIC::OBJECT);
- ASM_LOCATION("ICCompareStub[Objects]");
+void CompareICStub::GenerateObjects(MacroAssembler* masm) {
+ DCHECK(state() == CompareICState::OBJECT);
+ ASM_LOCATION("CompareICStub[Objects]");
Label miss;
}
-void ICCompareStub::GenerateKnownObjects(MacroAssembler* masm) {
- ASM_LOCATION("ICCompareStub[KnownObjects]");
+void CompareICStub::GenerateKnownObjects(MacroAssembler* masm) {
+ ASM_LOCATION("CompareICStub[KnownObjects]");
Label miss;
// This method handles the case where a compare stub had the wrong
// implementation. It calls a miss handler, which re-writes the stub. All other
-// ICCompareStub::Generate* methods should fall back into this one if their
+// CompareICStub::Generate* methods should fall back into this one if their
// operands were not the expected types.
-void ICCompareStub::GenerateMiss(MacroAssembler* masm) {
- ASM_LOCATION("ICCompareStub[Miss]");
+void CompareICStub::GenerateMiss(MacroAssembler* masm) {
+ ASM_LOCATION("CompareICStub[Miss]");
Register stub_entry = x11;
{
// Preserve some caller-saved registers.
__ Push(x1, x0, lr);
// Push the arguments.
- __ Mov(op, Smi::FromInt(op_));
+ __ Mov(op, Smi::FromInt(this->op()));
__ Push(left, right, op);
// Call the miss handler. This also pops the arguments.
}
-void StringHelper::GenerateHashInit(MacroAssembler* masm,
- Register hash,
- Register character) {
- DCHECK(!AreAliased(hash, character));
-
- // hash = character + (character << 10);
- __ LoadRoot(hash, Heap::kHashSeedRootIndex);
- // Untag smi seed and add the character.
- __ Add(hash, character, Operand::UntagSmi(hash));
-
- // Compute hashes modulo 2^32 using a 32-bit W register.
- Register hash_w = hash.W();
-
- // hash += hash << 10;
- __ Add(hash_w, hash_w, Operand(hash_w, LSL, 10));
- // hash ^= hash >> 6;
- __ Eor(hash_w, hash_w, Operand(hash_w, LSR, 6));
-}
-
-
-void StringHelper::GenerateHashAddCharacter(MacroAssembler* masm,
- Register hash,
- Register character) {
- DCHECK(!AreAliased(hash, character));
-
- // hash += character;
- __ Add(hash, hash, character);
-
- // Compute hashes modulo 2^32 using a 32-bit W register.
- Register hash_w = hash.W();
-
- // hash += hash << 10;
- __ Add(hash_w, hash_w, Operand(hash_w, LSL, 10));
- // hash ^= hash >> 6;
- __ Eor(hash_w, hash_w, Operand(hash_w, LSR, 6));
-}
-
-
-void StringHelper::GenerateHashGetHash(MacroAssembler* masm,
- Register hash,
- Register scratch) {
- // Compute hashes modulo 2^32 using a 32-bit W register.
- Register hash_w = hash.W();
- Register scratch_w = scratch.W();
- DCHECK(!AreAliased(hash_w, scratch_w));
-
- // hash += hash << 3;
- __ Add(hash_w, hash_w, Operand(hash_w, LSL, 3));
- // hash ^= hash >> 11;
- __ Eor(hash_w, hash_w, Operand(hash_w, LSR, 11));
- // hash += hash << 15;
- __ Add(hash_w, hash_w, Operand(hash_w, LSL, 15));
-
- __ Ands(hash_w, hash_w, String::kHashBitMask);
-
- // if (hash == 0) hash = 27;
- __ Mov(scratch_w, StringHasher::kZeroHash);
- __ Csel(hash_w, scratch_w, hash_w, eq);
-}
-
-
void SubStringStub::Generate(MacroAssembler* masm) {
ASM_LOCATION("SubStringStub::Generate");
Label runtime;
STATIC_ASSERT((kStringEncodingMask & kOneByteStringTag) != 0);
STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
__ Tbz(input_type, MaskToBit(kStringEncodingMask), &two_byte_slice);
- __ AllocateAsciiSlicedString(result_string, result_length, x3, x4,
- &runtime);
+ __ AllocateOneByteSlicedString(result_string, result_length, x3, x4,
+ &runtime);
__ B(&set_slice_header);
__ Bind(&two_byte_slice);
SeqOneByteString::kHeaderSize - kHeapObjectTag);
__ Bind(&allocate_result);
- // Sequential ASCII string. Allocate the result.
+ // Sequential one-byte string. Allocate the result.
STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0);
__ Tbz(input_type, MaskToBit(kStringEncodingMask), &two_byte_sequential);
- // Allocate and copy the resulting ASCII string.
- __ AllocateAsciiString(result_string, result_length, x3, x4, x5, &runtime);
+ // Allocate and copy the resulting one-byte string.
+ __ AllocateOneByteString(result_string, result_length, x3, x4, x5, &runtime);
// Locate first character of substring to copy.
__ Add(substring_char0, unpacked_char0, from);
}
-void StringCompareStub::GenerateFlatAsciiStringEquals(MacroAssembler* masm,
- Register left,
- Register right,
- Register scratch1,
- Register scratch2,
- Register scratch3) {
+void StringHelper::GenerateFlatOneByteStringEquals(
+ MacroAssembler* masm, Register left, Register right, Register scratch1,
+ Register scratch2, Register scratch3) {
DCHECK(!AreAliased(left, right, scratch1, scratch2, scratch3));
Register result = x0;
Register left_length = scratch1;
// Compare characters. Falls through if all characters are equal.
__ Bind(&compare_chars);
- GenerateAsciiCharsCompareLoop(masm, left, right, left_length, scratch2,
- scratch3, &strings_not_equal);
+ GenerateOneByteCharsCompareLoop(masm, left, right, left_length, scratch2,
+ scratch3, &strings_not_equal);
// Characters in strings are equal.
__ Mov(result, Smi::FromInt(EQUAL));
}
-void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
- Register left,
- Register right,
- Register scratch1,
- Register scratch2,
- Register scratch3,
- Register scratch4) {
+void StringHelper::GenerateCompareFlatOneByteStrings(
+ MacroAssembler* masm, Register left, Register right, Register scratch1,
+ Register scratch2, Register scratch3, Register scratch4) {
DCHECK(!AreAliased(left, right, scratch1, scratch2, scratch3, scratch4));
Label result_not_equal, compare_lengths;
__ Cbz(min_length, &compare_lengths);
// Compare loop.
- GenerateAsciiCharsCompareLoop(masm,
- left, right, min_length, scratch2, scratch4,
- &result_not_equal);
+ GenerateOneByteCharsCompareLoop(masm, left, right, min_length, scratch2,
+ scratch4, &result_not_equal);
// Compare lengths - strings up to min-length are equal.
__ Bind(&compare_lengths);
}
-void StringCompareStub::GenerateAsciiCharsCompareLoop(
- MacroAssembler* masm,
- Register left,
- Register right,
- Register length,
- Register scratch1,
- Register scratch2,
- Label* chars_not_equal) {
+void StringHelper::GenerateOneByteCharsCompareLoop(
+ MacroAssembler* masm, Register left, Register right, Register length,
+ Register scratch1, Register scratch2, Label* chars_not_equal) {
DCHECK(!AreAliased(left, right, length, scratch1, scratch2));
// Change index to run from -length to -1 by adding length to string
__ Bind(¬_same);
- // Check that both objects are sequential ASCII strings.
- __ JumpIfEitherIsNotSequentialAsciiStrings(left, right, x12, x13, &runtime);
+ // Check that both objects are sequential one-byte strings.
+ __ JumpIfEitherIsNotSequentialOneByteStrings(left, right, x12, x13, &runtime);
- // Compare flat ASCII strings natively. Remove arguments from stack first,
+ // Compare flat one-byte strings natively. Remove arguments from stack first,
// as this function will generate a return.
__ IncrementCounter(counters->string_compare_native(), 1, x3, x4);
- GenerateCompareFlatAsciiStrings(masm, left, right, x12, x13, x14, x15);
+ StringHelper::GenerateCompareFlatOneByteStrings(masm, left, right, x12, x13,
+ x14, x15);
__ Bind(&runtime);
// Tail call into the stub that handles binary operations with allocation
// sites.
- BinaryOpWithAllocationSiteStub stub(isolate(), state_);
+ BinaryOpWithAllocationSiteStub stub(isolate(), state());
__ TailCallStub(&stub);
}
// but we need to save them before using them.
regs_.Save(masm);
- if (remembered_set_action_ == EMIT_REMEMBERED_SET) {
+ if (remembered_set_action() == EMIT_REMEMBERED_SET) {
Label dont_need_remembered_set;
- Register value = regs_.scratch0();
- __ Ldr(value, MemOperand(regs_.address()));
- __ JumpIfNotInNewSpace(value, &dont_need_remembered_set);
+ Register val = regs_.scratch0();
+ __ Ldr(val, MemOperand(regs_.address()));
+ __ JumpIfNotInNewSpace(val, &dont_need_remembered_set);
- __ CheckPageFlagSet(regs_.object(),
- value,
- 1 << MemoryChunk::SCAN_ON_SCAVENGE,
+ __ CheckPageFlagSet(regs_.object(), val, 1 << MemoryChunk::SCAN_ON_SCAVENGE,
&dont_need_remembered_set);
// First notify the incremental marker if necessary, then update the
InformIncrementalMarker(masm);
regs_.Restore(masm); // Restore the extra scratch registers we used.
- __ RememberedSetHelper(object_,
- address_,
- value_, // scratch1
- save_fp_regs_mode_,
- MacroAssembler::kReturnAtEnd);
+ __ RememberedSetHelper(object(), address(),
+ value(), // scratch1
+ save_fp_regs_mode(), MacroAssembler::kReturnAtEnd);
__ Bind(&dont_need_remembered_set);
}
void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) {
- regs_.SaveCallerSaveRegisters(masm, save_fp_regs_mode_);
+ regs_.SaveCallerSaveRegisters(masm, save_fp_regs_mode());
Register address =
x0.Is(regs_.address()) ? regs_.scratch0() : regs_.address();
DCHECK(!address.Is(regs_.object()));
isolate());
__ CallCFunction(function, 3, 0);
- regs_.RestoreCallerSaveRegisters(masm, save_fp_regs_mode_);
+ regs_.RestoreCallerSaveRegisters(masm, save_fp_regs_mode());
}
regs_.Restore(masm); // Restore the extra scratch registers we used.
if (on_no_need == kUpdateRememberedSetOnNoNeedToInformIncrementalMarker) {
- __ RememberedSetHelper(object_,
- address_,
- value_, // scratch1
- save_fp_regs_mode_,
- MacroAssembler::kReturnAtEnd);
+ __ RememberedSetHelper(object(), address(),
+ value(), // scratch1
+ save_fp_regs_mode(), MacroAssembler::kReturnAtEnd);
} else {
__ Ret();
}
__ Bind(&on_black);
// Get the value from the slot.
- Register value = regs_.scratch0();
- __ Ldr(value, MemOperand(regs_.address()));
+ Register val = regs_.scratch0();
+ __ Ldr(val, MemOperand(regs_.address()));
if (mode == INCREMENTAL_COMPACTION) {
Label ensure_not_white;
- __ CheckPageFlagClear(value,
- regs_.scratch1(),
+ __ CheckPageFlagClear(val, regs_.scratch1(),
MemoryChunk::kEvacuationCandidateMask,
&ensure_not_white);
// We need extra registers for this, so we push the object and the address
// register temporarily.
__ Push(regs_.address(), regs_.object());
- __ EnsureNotWhite(value,
+ __ EnsureNotWhite(val,
regs_.scratch1(), // Scratch.
regs_.object(), // Scratch.
regs_.address(), // Scratch.
regs_.Restore(masm); // Restore the extra scratch registers we used.
if (on_no_need == kUpdateRememberedSetOnNoNeedToInformIncrementalMarker) {
- __ RememberedSetHelper(object_,
- address_,
- value_, // scratch1
- save_fp_regs_mode_,
- MacroAssembler::kReturnAtEnd);
+ __ RememberedSetHelper(object(), address(),
+ value(), // scratch1
+ save_fp_regs_mode(), MacroAssembler::kReturnAtEnd);
} else {
__ Ret();
}
__ adr(xzr, &skip_to_incremental_compacting);
}
- if (remembered_set_action_ == EMIT_REMEMBERED_SET) {
- __ RememberedSetHelper(object_,
- address_,
- value_, // scratch1
- save_fp_regs_mode_,
- MacroAssembler::kReturnAtEnd);
+ if (remembered_set_action() == EMIT_REMEMBERED_SET) {
+ __ RememberedSetHelper(object(), address(),
+ value(), // scratch1
+ save_fp_regs_mode(), MacroAssembler::kReturnAtEnd);
}
__ Ret();
int parameter_count_offset =
StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset;
__ Ldr(x1, MemOperand(fp, parameter_count_offset));
- if (function_mode_ == JS_FUNCTION_STUB_MODE) {
+ if (function_mode() == JS_FUNCTION_STUB_MODE) {
__ Add(x1, x1, 1);
}
masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE);
}
+void LoadICTrampolineStub::Generate(MacroAssembler* masm) {
+ EmitLoadTypeFeedbackVector(masm, VectorLoadICDescriptor::VectorRegister());
+ VectorLoadStub stub(isolate(), state());
+ __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
+}
+
+
+void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
+ EmitLoadTypeFeedbackVector(masm, VectorLoadICDescriptor::VectorRegister());
+ VectorKeyedLoadStub stub(isolate());
+ __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
+}
+
+
static unsigned int GetProfileEntryHookCallSize(MacroAssembler* masm) {
// The entry hook is a "BumpSystemStackPointer" instruction (sub),
// followed by a "Push lr" instruction, followed by a call.
__ Ldr(entity_name, FieldMemOperand(entity_name, HeapObject::kMapOffset));
__ Ldrb(entity_name,
FieldMemOperand(entity_name, Map::kInstanceTypeOffset));
- __ JumpIfNotUniqueName(entity_name, miss);
+ __ JumpIfNotUniqueNameInstanceType(entity_name, miss);
__ Bind(&good);
}
__ Cmp(entry_key, key);
__ B(eq, &in_dictionary);
- if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) {
+ if (i != kTotalProbes - 1 && mode() == NEGATIVE_LOOKUP) {
// Check if the entry name is not a unique name.
__ Ldr(entry_key, FieldMemOperand(entry_key, HeapObject::kMapOffset));
__ Ldrb(entry_key, FieldMemOperand(entry_key, Map::kInstanceTypeOffset));
- __ JumpIfNotUniqueName(entry_key, &maybe_in_dictionary);
+ __ JumpIfNotUniqueNameInstanceType(entry_key, &maybe_in_dictionary);
}
}
// If we are doing negative lookup then probing failure should be
// treated as a lookup success. For positive lookup, probing failure
// should be treated as lookup failure.
- if (mode_ == POSITIVE_LOOKUP) {
+ if (mode() == POSITIVE_LOOKUP) {
__ Mov(result, 0);
__ Ret();
}
MacroAssembler* masm,
AllocationSiteOverrideMode mode) {
Register argc = x0;
- if (argument_count_ == ANY) {
+ if (argument_count() == ANY) {
Label zero_case, n_case;
__ Cbz(argc, &zero_case);
__ Cmp(argc, 1);
// N arguments.
CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
- } else if (argument_count_ == NONE) {
+ } else if (argument_count() == NONE) {
CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
- } else if (argument_count_ == ONE) {
+ } else if (argument_count() == ONE) {
CreateArrayDispatchOneArgument(masm, mode);
- } else if (argument_count_ == MORE_THAN_ONE) {
+ } else if (argument_count() == MORE_THAN_ONE) {
CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
} else {
UNREACHABLE();
void ArrayConstructorStub::Generate(MacroAssembler* masm) {
ASM_LOCATION("ArrayConstructorStub::Generate");
// ----------- S t a t e -------------
- // -- x0 : argc (only if argument_count_ == ANY)
+ // -- x0 : argc (only if argument_count() == ANY)
// -- x1 : constructor
// -- x2 : AllocationSite or undefined
// -- sp[0] : return address
Register api_function_address = x1;
Register context = cp;
- int argc = ArgumentBits::decode(bit_field_);
- bool is_store = IsStoreBits::decode(bit_field_);
- bool call_data_undefined = CallDataUndefinedBits::decode(bit_field_);
+ int argc = this->argc();
+ bool is_store = this->is_store();
+ bool call_data_undefined = this->call_data_undefined();
typedef FunctionCallbackArguments FCA;
// -- x2 : api_function_address
// -----------------------------------
- Register api_function_address = x2;
+ Register api_function_address = ApiGetterDescriptor::function_address();
+ DCHECK(api_function_address.is(x2));
__ Mov(x0, masm->StackPointer()); // x0 = Handle<Name>
__ Add(x1, x0, 1 * kPointerSize); // x1 = PCA