| Index: src/x64/full-codegen-x64.cc
|
| diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
|
| index 577c92cd62802713d09cbbc28e18b800f80d382d..25f9c1d7a4df6a1f469c850939901739b163c72b 100644
|
| --- a/src/x64/full-codegen-x64.cc
|
| +++ b/src/x64/full-codegen-x64.cc
|
| @@ -1904,76 +1904,6 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitInlineRuntimeCall(CallRuntime* expr) {
|
| - Handle<String> name = expr->name();
|
| - if (strcmp("_IsSmi", *name->ToCString()) == 0) {
|
| - EmitIsSmi(expr->arguments());
|
| - } else if (strcmp("_IsNonNegativeSmi", *name->ToCString()) == 0) {
|
| - EmitIsNonNegativeSmi(expr->arguments());
|
| - } else if (strcmp("_IsObject", *name->ToCString()) == 0) {
|
| - EmitIsObject(expr->arguments());
|
| - } else if (strcmp("_IsUndetectableObject", *name->ToCString()) == 0) {
|
| - EmitIsUndetectableObject(expr->arguments());
|
| - } else if (strcmp("_IsFunction", *name->ToCString()) == 0) {
|
| - EmitIsFunction(expr->arguments());
|
| - } else if (strcmp("_IsArray", *name->ToCString()) == 0) {
|
| - EmitIsArray(expr->arguments());
|
| - } else if (strcmp("_IsRegExp", *name->ToCString()) == 0) {
|
| - EmitIsRegExp(expr->arguments());
|
| - } else if (strcmp("_IsConstructCall", *name->ToCString()) == 0) {
|
| - EmitIsConstructCall(expr->arguments());
|
| - } else if (strcmp("_ObjectEquals", *name->ToCString()) == 0) {
|
| - EmitObjectEquals(expr->arguments());
|
| - } else if (strcmp("_Arguments", *name->ToCString()) == 0) {
|
| - EmitArguments(expr->arguments());
|
| - } else if (strcmp("_ArgumentsLength", *name->ToCString()) == 0) {
|
| - EmitArgumentsLength(expr->arguments());
|
| - } else if (strcmp("_ClassOf", *name->ToCString()) == 0) {
|
| - EmitClassOf(expr->arguments());
|
| - } else if (strcmp("_Log", *name->ToCString()) == 0) {
|
| - EmitLog(expr->arguments());
|
| - } else if (strcmp("_RandomHeapNumber", *name->ToCString()) == 0) {
|
| - EmitRandomHeapNumber(expr->arguments());
|
| - } else if (strcmp("_SubString", *name->ToCString()) == 0) {
|
| - EmitSubString(expr->arguments());
|
| - } else if (strcmp("_RegExpExec", *name->ToCString()) == 0) {
|
| - EmitRegExpExec(expr->arguments());
|
| - } else if (strcmp("_ValueOf", *name->ToCString()) == 0) {
|
| - EmitValueOf(expr->arguments());
|
| - } else if (strcmp("_SetValueOf", *name->ToCString()) == 0) {
|
| - EmitSetValueOf(expr->arguments());
|
| - } else if (strcmp("_NumberToString", *name->ToCString()) == 0) {
|
| - EmitNumberToString(expr->arguments());
|
| - } else if (strcmp("_CharFromCode", *name->ToCString()) == 0) {
|
| - EmitCharFromCode(expr->arguments());
|
| - } else if (strcmp("_FastCharCodeAt", *name->ToCString()) == 0) {
|
| - EmitFastCharCodeAt(expr->arguments());
|
| - } else if (strcmp("_StringAdd", *name->ToCString()) == 0) {
|
| - EmitStringAdd(expr->arguments());
|
| - } else if (strcmp("_StringCompare", *name->ToCString()) == 0) {
|
| - EmitStringCompare(expr->arguments());
|
| - } else if (strcmp("_MathPow", *name->ToCString()) == 0) {
|
| - EmitMathPow(expr->arguments());
|
| - } else if (strcmp("_MathSin", *name->ToCString()) == 0) {
|
| - EmitMathSin(expr->arguments());
|
| - } else if (strcmp("_MathCos", *name->ToCString()) == 0) {
|
| - EmitMathCos(expr->arguments());
|
| - } else if (strcmp("_MathSqrt", *name->ToCString()) == 0) {
|
| - EmitMathSqrt(expr->arguments());
|
| - } else if (strcmp("_CallFunction", *name->ToCString()) == 0) {
|
| - EmitCallFunction(expr->arguments());
|
| - } else if (strcmp("_RegExpConstructResult", *name->ToCString()) == 0) {
|
| - EmitRegExpConstructResult(expr->arguments());
|
| - } else if (strcmp("_SwapElements", *name->ToCString()) == 0) {
|
| - EmitSwapElements(expr->arguments());
|
| - } else if (strcmp("_GetFromCache", *name->ToCString()) == 0) {
|
| - EmitGetFromCache(expr->arguments());
|
| - } else {
|
| - UNREACHABLE();
|
| - }
|
| -}
|
| -
|
| -
|
| void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) {
|
| ASSERT(args->length() == 1);
|
|
|
| @@ -2412,46 +2342,120 @@ void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) {
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitCharFromCode(ZoneList<Expression*>* args) {
|
| +void FullCodeGenerator::EmitStringCharFromCode(ZoneList<Expression*>* args) {
|
| ASSERT(args->length() == 1);
|
|
|
| VisitForValue(args->at(0), kAccumulator);
|
|
|
| - Label slow_case, done;
|
| - // Fast case of Heap::LookupSingleCharacterStringFromCode.
|
| - __ JumpIfNotSmi(rax, &slow_case);
|
| - __ SmiToInteger32(rcx, rax);
|
| - __ cmpl(rcx, Immediate(String::kMaxAsciiCharCode));
|
| - __ j(above, &slow_case);
|
| + Label done;
|
| + StringCharFromCodeGenerator generator(rax, rbx);
|
| + generator.GenerateFast(masm_);
|
| + __ jmp(&done);
|
|
|
| - __ Move(rbx, Factory::single_character_string_cache());
|
| - __ movq(rbx, FieldOperand(rbx,
|
| - rcx,
|
| - times_pointer_size,
|
| - FixedArray::kHeaderSize));
|
| + NopRuntimeCallHelper call_helper;
|
| + generator.GenerateSlow(masm_, call_helper);
|
|
|
| - __ CompareRoot(rbx, Heap::kUndefinedValueRootIndex);
|
| - __ j(equal, &slow_case);
|
| - __ movq(rax, rbx);
|
| + __ bind(&done);
|
| + Apply(context_, rbx);
|
| +}
|
| +
|
| +
|
| +void FullCodeGenerator::EmitStringCharCodeAt(ZoneList<Expression*>* args) {
|
| + ASSERT(args->length() == 2);
|
| +
|
| + VisitForValue(args->at(0), kStack);
|
| + VisitForValue(args->at(1), kAccumulator);
|
| +
|
| + Register object = rbx;
|
| + Register index = rax;
|
| + Register scratch = rcx;
|
| + Register result = rdx;
|
| +
|
| + __ pop(object);
|
| +
|
| + Label need_conversion;
|
| + Label index_out_of_range;
|
| + Label done;
|
| + StringCharCodeAtGenerator generator(object,
|
| + index,
|
| + scratch,
|
| + result,
|
| + &need_conversion,
|
| + &need_conversion,
|
| + &index_out_of_range,
|
| + STRING_ANY_NUMBER_INDEX);
|
| + generator.GenerateFast(masm_);
|
| __ jmp(&done);
|
|
|
| - __ bind(&slow_case);
|
| - __ push(rax);
|
| - __ CallRuntime(Runtime::kCharFromCode, 1);
|
| + __ bind(&index_out_of_range);
|
| + // When the index is out of range, the spec requires us to return
|
| + // NaN.
|
| + __ LoadRoot(result, Heap::kNanValueRootIndex);
|
| + __ jmp(&done);
|
| +
|
| + __ bind(&need_conversion);
|
| + // Move the undefined value into the result register, which will
|
| + // trigger conversion.
|
| + __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
|
| + __ jmp(&done);
|
| +
|
| + NopRuntimeCallHelper call_helper;
|
| + generator.GenerateSlow(masm_, call_helper);
|
|
|
| __ bind(&done);
|
| - Apply(context_, rax);
|
| + Apply(context_, result);
|
| }
|
|
|
|
|
| -void FullCodeGenerator::EmitFastCharCodeAt(ZoneList<Expression*>* args) {
|
| - // TODO(fsc): Port the complete implementation from the classic back-end.
|
| - // Move the undefined value into the result register, which will
|
| - // trigger the slow case.
|
| - __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
|
| - Apply(context_, rax);
|
| +void FullCodeGenerator::EmitStringCharAt(ZoneList<Expression*>* args) {
|
| + ASSERT(args->length() == 2);
|
| +
|
| + VisitForValue(args->at(0), kStack);
|
| + VisitForValue(args->at(1), kAccumulator);
|
| +
|
| + Register object = rbx;
|
| + Register index = rax;
|
| + Register scratch1 = rcx;
|
| + Register scratch2 = rdx;
|
| + Register result = rax;
|
| +
|
| + __ pop(object);
|
| +
|
| + Label need_conversion;
|
| + Label index_out_of_range;
|
| + Label done;
|
| + StringCharAtGenerator generator(object,
|
| + index,
|
| + scratch1,
|
| + scratch2,
|
| + result,
|
| + &need_conversion,
|
| + &need_conversion,
|
| + &index_out_of_range,
|
| + STRING_ANY_NUMBER_INDEX);
|
| + generator.GenerateFast(masm_);
|
| + __ jmp(&done);
|
| +
|
| + __ bind(&index_out_of_range);
|
| + // When the index is out of range, the spec requires us to return
|
| + // the empty string.
|
| + __ LoadRoot(result, Heap::kEmptyStringRootIndex);
|
| + __ jmp(&done);
|
| +
|
| + __ bind(&need_conversion);
|
| + // Move smi zero into the result register, which will trigger
|
| + // conversion.
|
| + __ Move(result, Smi::FromInt(0));
|
| + __ jmp(&done);
|
| +
|
| + NopRuntimeCallHelper call_helper;
|
| + generator.GenerateSlow(masm_, call_helper);
|
| +
|
| + __ bind(&done);
|
| + Apply(context_, result);
|
| }
|
|
|
| +
|
| void FullCodeGenerator::EmitStringAdd(ZoneList<Expression*>* args) {
|
| ASSERT_EQ(2, args->length());
|
|
|
|
|