| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 | 136 |
| 137 #ifdef DEBUG | 137 #ifdef DEBUG |
| 138 if (strlen(FLAG_stop_at) > 0 && | 138 if (strlen(FLAG_stop_at) > 0 && |
| 139 info_->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { | 139 info_->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { |
| 140 __ stop("stop_at"); | 140 __ stop("stop_at"); |
| 141 } | 141 } |
| 142 #endif | 142 #endif |
| 143 | 143 |
| 144 // r1: Callee's JS function. | 144 // r1: Callee's JS function. |
| 145 // cp: Callee's context. | 145 // cp: Callee's context. |
| 146 // pp: Callee's constant pool pointer (if FLAG_enable_ool_constant_pool) |
| 146 // fp: Caller's frame pointer. | 147 // fp: Caller's frame pointer. |
| 147 // lr: Caller's pc. | 148 // lr: Caller's pc. |
| 148 | 149 |
| 149 // Strict mode functions and builtins need to replace the receiver | 150 // Strict mode functions and builtins need to replace the receiver |
| 150 // with undefined when called as functions (without an explicit | 151 // with undefined when called as functions (without an explicit |
| 151 // receiver object). r5 is zero for method calls and non-zero for | 152 // receiver object). r5 is zero for method calls and non-zero for |
| 152 // function calls. | 153 // function calls. |
| 153 if (!info_->is_classic_mode() || info_->is_native()) { | 154 if (!info_->is_classic_mode() || info_->is_native()) { |
| 154 __ cmp(r5, Operand::Zero()); | 155 __ cmp(r5, Operand::Zero()); |
| 155 int receiver_offset = scope()->num_parameters() * kPointerSize; | 156 int receiver_offset = scope()->num_parameters() * kPointerSize; |
| 156 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); | 157 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
| 157 __ str(r2, MemOperand(sp, receiver_offset), ne); | 158 __ str(r2, MemOperand(sp, receiver_offset), ne); |
| 158 } | 159 } |
| 159 } | 160 } |
| 160 | 161 |
| 161 info()->set_prologue_offset(masm_->pc_offset()); | 162 info()->set_prologue_offset(masm_->pc_offset()); |
| 162 if (NeedsEagerFrame()) { | 163 if (NeedsEagerFrame()) { |
| 163 __ Prologue(info()->IsStub() ? BUILD_STUB_FRAME : BUILD_FUNCTION_FRAME); | 164 __ Prologue(info()->IsStub() ? BUILD_STUB_FRAME : BUILD_FUNCTION_FRAME); |
| 164 frame_is_built_ = true; | 165 frame_is_built_ = true; |
| 165 info_->AddNoFrameRange(0, masm_->pc_offset()); | 166 info_->AddNoFrameRange(0, masm_->pc_offset()); |
| 167 __ LoadConstantPoolPointerRegister(); |
| 166 } | 168 } |
| 167 | 169 |
| 168 // Reserve space for the stack slots needed by the code. | 170 // Reserve space for the stack slots needed by the code. |
| 169 int slots = GetStackSlotCount(); | 171 int slots = GetStackSlotCount(); |
| 170 if (slots > 0) { | 172 if (slots > 0) { |
| 171 if (FLAG_debug_code) { | 173 if (FLAG_debug_code) { |
| 172 __ sub(sp, sp, Operand(slots * kPointerSize)); | 174 __ sub(sp, sp, Operand(slots * kPointerSize)); |
| 173 __ push(r0); | 175 __ push(r0); |
| 174 __ push(r1); | 176 __ push(r1); |
| 175 __ add(r0, sp, Operand(slots * kPointerSize)); | 177 __ add(r0, sp, Operand(slots * kPointerSize)); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 "-------------------- Deferred %s --------------------", | 273 "-------------------- Deferred %s --------------------", |
| 272 code->instruction_index(), | 274 code->instruction_index(), |
| 273 code->instr()->hydrogen_value()->id(), | 275 code->instr()->hydrogen_value()->id(), |
| 274 code->instr()->Mnemonic()); | 276 code->instr()->Mnemonic()); |
| 275 __ bind(code->entry()); | 277 __ bind(code->entry()); |
| 276 if (NeedsDeferredFrame()) { | 278 if (NeedsDeferredFrame()) { |
| 277 Comment(";;; Build frame"); | 279 Comment(";;; Build frame"); |
| 278 ASSERT(!frame_is_built_); | 280 ASSERT(!frame_is_built_); |
| 279 ASSERT(info()->IsStub()); | 281 ASSERT(info()->IsStub()); |
| 280 frame_is_built_ = true; | 282 frame_is_built_ = true; |
| 281 __ stm(db_w, sp, cp.bit() | fp.bit() | lr.bit()); | 283 __ PushFixedFrame(); |
| 282 __ mov(scratch0(), Operand(Smi::FromInt(StackFrame::STUB))); | 284 __ mov(scratch0(), Operand(Smi::FromInt(StackFrame::STUB))); |
| 283 __ push(scratch0()); | 285 __ push(scratch0()); |
| 284 __ add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); | 286 __ add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); |
| 285 Comment(";;; Deferred code"); | 287 Comment(";;; Deferred code"); |
| 286 } | 288 } |
| 287 code->Generate(); | 289 code->Generate(); |
| 288 if (NeedsDeferredFrame()) { | 290 if (NeedsDeferredFrame()) { |
| 289 Comment(";;; Destroy frame"); | 291 Comment(";;; Destroy frame"); |
| 290 ASSERT(frame_is_built_); | 292 ASSERT(frame_is_built_); |
| 291 __ pop(ip); | 293 __ pop(ip); |
| 292 __ ldm(ia_w, sp, cp.bit() | fp.bit() | lr.bit()); | 294 __ PopFixedFrame(); |
| 293 frame_is_built_ = false; | 295 frame_is_built_ = false; |
| 294 } | 296 } |
| 295 __ jmp(code->exit()); | 297 __ jmp(code->exit()); |
| 296 } | 298 } |
| 297 } | 299 } |
| 298 | 300 |
| 299 // Force constant pool emission at the end of the deferred code to make | 301 // Force constant pool emission at the end of the deferred code to make |
| 300 // sure that no constant pools are emitted after. | 302 // sure that no constant pools are emitted after. |
| 301 masm()->CheckConstPool(true, false); | 303 masm()->CheckConstPool(true, false); |
| 302 | 304 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 333 } else { | 335 } else { |
| 334 Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id); | 336 Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id); |
| 335 } | 337 } |
| 336 if (deopt_jump_table_[i].needs_frame) { | 338 if (deopt_jump_table_[i].needs_frame) { |
| 337 ASSERT(!info()->saves_caller_doubles()); | 339 ASSERT(!info()->saves_caller_doubles()); |
| 338 __ mov(ip, Operand(ExternalReference::ForDeoptEntry(entry))); | 340 __ mov(ip, Operand(ExternalReference::ForDeoptEntry(entry))); |
| 339 if (needs_frame.is_bound()) { | 341 if (needs_frame.is_bound()) { |
| 340 __ b(&needs_frame); | 342 __ b(&needs_frame); |
| 341 } else { | 343 } else { |
| 342 __ bind(&needs_frame); | 344 __ bind(&needs_frame); |
| 343 __ stm(db_w, sp, cp.bit() | fp.bit() | lr.bit()); | 345 __ PushFixedFrame(); |
| 344 // This variant of deopt can only be used with stubs. Since we don't | 346 // This variant of deopt can only be used with stubs. Since we don't |
| 345 // have a function pointer to install in the stack frame that we're | 347 // have a function pointer to install in the stack frame that we're |
| 346 // building, install a special marker there instead. | 348 // building, install a special marker there instead. |
| 347 ASSERT(info()->IsStub()); | 349 ASSERT(info()->IsStub()); |
| 348 __ mov(scratch0(), Operand(Smi::FromInt(StackFrame::STUB))); | 350 __ mov(scratch0(), Operand(Smi::FromInt(StackFrame::STUB))); |
| 349 __ push(scratch0()); | 351 __ push(scratch0()); |
| 350 __ add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); | 352 __ add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); |
| 351 __ mov(lr, Operand(pc), LeaveCC, al); | 353 __ mov(lr, Operand(pc), LeaveCC, al); |
| 352 __ mov(pc, ip); | 354 __ mov(pc, ip); |
| 353 } | 355 } |
| (...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1078 case CodeStub::SubString: { | 1080 case CodeStub::SubString: { |
| 1079 SubStringStub stub; | 1081 SubStringStub stub; |
| 1080 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1082 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 1081 break; | 1083 break; |
| 1082 } | 1084 } |
| 1083 case CodeStub::StringCompare: { | 1085 case CodeStub::StringCompare: { |
| 1084 StringCompareStub stub; | 1086 StringCompareStub stub; |
| 1085 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1087 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 1086 break; | 1088 break; |
| 1087 } | 1089 } |
| 1088 case CodeStub::TranscendentalCache: { | |
| 1089 __ ldr(r0, MemOperand(sp, 0)); | |
| 1090 TranscendentalCacheStub stub(instr->transcendental_type(), | |
| 1091 TranscendentalCacheStub::TAGGED); | |
| 1092 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | |
| 1093 break; | |
| 1094 } | |
| 1095 default: | 1090 default: |
| 1096 UNREACHABLE(); | 1091 UNREACHABLE(); |
| 1097 } | 1092 } |
| 1098 } | 1093 } |
| 1099 | 1094 |
| 1100 | 1095 |
| 1101 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { | 1096 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { |
| 1102 GenerateOsrPrologue(); | 1097 GenerateOsrPrologue(); |
| 1103 } | 1098 } |
| 1104 | 1099 |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1407 __ cmp(right, Operand::Zero()); | 1402 __ cmp(right, Operand::Zero()); |
| 1408 } | 1403 } |
| 1409 __ b(pl, &positive); | 1404 __ b(pl, &positive); |
| 1410 __ cmp(left, Operand::Zero()); | 1405 __ cmp(left, Operand::Zero()); |
| 1411 DeoptimizeIf(eq, instr->environment()); | 1406 DeoptimizeIf(eq, instr->environment()); |
| 1412 __ bind(&positive); | 1407 __ bind(&positive); |
| 1413 } | 1408 } |
| 1414 | 1409 |
| 1415 // Check for (kMinInt / -1). | 1410 // Check for (kMinInt / -1). |
| 1416 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 1411 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
| 1417 Label left_not_min_int; | |
| 1418 __ cmp(left, Operand(kMinInt)); | 1412 __ cmp(left, Operand(kMinInt)); |
| 1419 __ b(ne, &left_not_min_int); | 1413 __ cmp(right, Operand(-1), eq); |
| 1420 __ cmp(right, Operand(-1)); | |
| 1421 DeoptimizeIf(eq, instr->environment()); | 1414 DeoptimizeIf(eq, instr->environment()); |
| 1422 __ bind(&left_not_min_int); | |
| 1423 } | 1415 } |
| 1424 | 1416 |
| 1425 if (CpuFeatures::IsSupported(SUDIV)) { | 1417 if (CpuFeatures::IsSupported(SUDIV)) { |
| 1426 CpuFeatureScope scope(masm(), SUDIV); | 1418 CpuFeatureScope scope(masm(), SUDIV); |
| 1427 __ sdiv(result, left, right); | 1419 __ sdiv(result, left, right); |
| 1428 | 1420 |
| 1429 if (!instr->hydrogen()->CheckFlag( | 1421 if (!instr->hydrogen()->CheckFlag( |
| 1430 HInstruction::kAllUsesTruncatingToInt32)) { | 1422 HInstruction::kAllUsesTruncatingToInt32)) { |
| 1431 // Compute remainder and deopt if it's not zero. | 1423 // Compute remainder and deopt if it's not zero. |
| 1432 const Register remainder = scratch0(); | 1424 const Register remainder = scratch0(); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1511 } else { | 1503 } else { |
| 1512 CpuFeatureScope scope(masm(), SUDIV); | 1504 CpuFeatureScope scope(masm(), SUDIV); |
| 1513 const Register right = ToRegister(instr->right()); | 1505 const Register right = ToRegister(instr->right()); |
| 1514 | 1506 |
| 1515 // Check for x / 0. | 1507 // Check for x / 0. |
| 1516 __ cmp(right, Operand::Zero()); | 1508 __ cmp(right, Operand::Zero()); |
| 1517 DeoptimizeIf(eq, instr->environment()); | 1509 DeoptimizeIf(eq, instr->environment()); |
| 1518 | 1510 |
| 1519 // Check for (kMinInt / -1). | 1511 // Check for (kMinInt / -1). |
| 1520 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 1512 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
| 1521 Label left_not_min_int; | |
| 1522 __ cmp(left, Operand(kMinInt)); | 1513 __ cmp(left, Operand(kMinInt)); |
| 1523 __ b(ne, &left_not_min_int); | 1514 __ cmp(right, Operand(-1), eq); |
| 1524 __ cmp(right, Operand(-1)); | |
| 1525 DeoptimizeIf(eq, instr->environment()); | 1515 DeoptimizeIf(eq, instr->environment()); |
| 1526 __ bind(&left_not_min_int); | |
| 1527 } | 1516 } |
| 1528 | 1517 |
| 1529 // Check for (0 / -x) that will produce negative zero. | 1518 // Check for (0 / -x) that will produce negative zero. |
| 1530 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1519 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1531 __ cmp(right, Operand::Zero()); | 1520 __ cmp(right, Operand::Zero()); |
| 1532 __ cmp(left, Operand::Zero(), mi); | 1521 __ cmp(left, Operand::Zero(), mi); |
| 1533 // "right" can't be null because the code would have already been | 1522 // "right" can't be null because the code would have already been |
| 1534 // deoptimized. The Z flag is set only if (right < 0) and (left == 0). | 1523 // deoptimized. The Z flag is set only if (right < 0) and (left == 0). |
| 1535 // In this case we need to deoptimize to produce a -0. | 1524 // In this case we need to deoptimize to produce a -0. |
| 1536 DeoptimizeIf(eq, instr->environment()); | 1525 DeoptimizeIf(eq, instr->environment()); |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1885 if (!instr->hydrogen()->value()->IsHeapObject()) { | 1874 if (!instr->hydrogen()->value()->IsHeapObject()) { |
| 1886 // If the object is a smi return the object. | 1875 // If the object is a smi return the object. |
| 1887 __ SmiTst(input); | 1876 __ SmiTst(input); |
| 1888 __ Move(result, input, eq); | 1877 __ Move(result, input, eq); |
| 1889 __ b(eq, &done); | 1878 __ b(eq, &done); |
| 1890 } | 1879 } |
| 1891 | 1880 |
| 1892 // If the object is not a value type, return the object. | 1881 // If the object is not a value type, return the object. |
| 1893 __ CompareObjectType(input, map, map, JS_VALUE_TYPE); | 1882 __ CompareObjectType(input, map, map, JS_VALUE_TYPE); |
| 1894 __ Move(result, input, ne); | 1883 __ Move(result, input, ne); |
| 1895 __ b(ne, &done); | 1884 __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset), eq); |
| 1896 __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset)); | |
| 1897 | 1885 |
| 1898 __ bind(&done); | 1886 __ bind(&done); |
| 1899 } | 1887 } |
| 1900 | 1888 |
| 1901 | 1889 |
| 1902 void LCodeGen::DoDateField(LDateField* instr) { | 1890 void LCodeGen::DoDateField(LDateField* instr) { |
| 1903 Register object = ToRegister(instr->date()); | 1891 Register object = ToRegister(instr->date()); |
| 1904 Register result = ToRegister(instr->result()); | 1892 Register result = ToRegister(instr->result()); |
| 1905 Register scratch = ToRegister(instr->temp()); | 1893 Register scratch = ToRegister(instr->temp()); |
| 1906 Smi* index = instr->index(); | 1894 Smi* index = instr->index(); |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2127 case Token::MUL: | 2115 case Token::MUL: |
| 2128 __ vmul(result, left, right); | 2116 __ vmul(result, left, right); |
| 2129 break; | 2117 break; |
| 2130 case Token::DIV: | 2118 case Token::DIV: |
| 2131 __ vdiv(result, left, right); | 2119 __ vdiv(result, left, right); |
| 2132 break; | 2120 break; |
| 2133 case Token::MOD: { | 2121 case Token::MOD: { |
| 2134 __ PrepareCallCFunction(0, 2, scratch0()); | 2122 __ PrepareCallCFunction(0, 2, scratch0()); |
| 2135 __ SetCallCDoubleArguments(left, right); | 2123 __ SetCallCDoubleArguments(left, right); |
| 2136 __ CallCFunction( | 2124 __ CallCFunction( |
| 2137 ExternalReference::double_fp_operation(Token::MOD, isolate()), | 2125 ExternalReference::mod_two_doubles_operation(isolate()), |
| 2138 0, 2); | 2126 0, 2); |
| 2139 // Move the result in the double result register. | 2127 // Move the result in the double result register. |
| 2140 __ GetCFunctionDoubleResult(result); | 2128 __ GetCFunctionDoubleResult(result); |
| 2141 break; | 2129 break; |
| 2142 } | 2130 } |
| 2143 default: | 2131 default: |
| 2144 UNREACHABLE(); | 2132 UNREACHABLE(); |
| 2145 break; | 2133 break; |
| 2146 } | 2134 } |
| 2147 } | 2135 } |
| (...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2918 // safe to write to the context register. | 2906 // safe to write to the context register. |
| 2919 __ push(r0); | 2907 __ push(r0); |
| 2920 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2908 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 2921 __ CallRuntime(Runtime::kTraceExit, 1); | 2909 __ CallRuntime(Runtime::kTraceExit, 1); |
| 2922 } | 2910 } |
| 2923 if (info()->saves_caller_doubles()) { | 2911 if (info()->saves_caller_doubles()) { |
| 2924 RestoreCallerDoubles(); | 2912 RestoreCallerDoubles(); |
| 2925 } | 2913 } |
| 2926 int no_frame_start = -1; | 2914 int no_frame_start = -1; |
| 2927 if (NeedsEagerFrame()) { | 2915 if (NeedsEagerFrame()) { |
| 2928 __ mov(sp, fp); | 2916 no_frame_start = masm_->LeaveFrame(StackFrame::JAVA_SCRIPT); |
| 2929 no_frame_start = masm_->pc_offset(); | |
| 2930 __ ldm(ia_w, sp, fp.bit() | lr.bit()); | |
| 2931 } | 2917 } |
| 2932 if (instr->has_constant_parameter_count()) { | 2918 if (instr->has_constant_parameter_count()) { |
| 2933 int parameter_count = ToInteger32(instr->constant_parameter_count()); | 2919 int parameter_count = ToInteger32(instr->constant_parameter_count()); |
| 2934 int32_t sp_delta = (parameter_count + 1) * kPointerSize; | 2920 int32_t sp_delta = (parameter_count + 1) * kPointerSize; |
| 2935 if (sp_delta != 0) { | 2921 if (sp_delta != 0) { |
| 2936 __ add(sp, sp, Operand(sp_delta)); | 2922 __ add(sp, sp, Operand(sp_delta)); |
| 2937 } | 2923 } |
| 2938 } else { | 2924 } else { |
| 2939 Register reg = ToRegister(instr->parameter_count()); | 2925 Register reg = ToRegister(instr->parameter_count()); |
| 2940 // The argument count parameter is a smi | 2926 // The argument count parameter is a smi |
| (...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3494 __ b(eq, &global_object); | 3480 __ b(eq, &global_object); |
| 3495 | 3481 |
| 3496 // Deoptimize if the receiver is not a JS object. | 3482 // Deoptimize if the receiver is not a JS object. |
| 3497 __ SmiTst(receiver); | 3483 __ SmiTst(receiver); |
| 3498 DeoptimizeIf(eq, instr->environment()); | 3484 DeoptimizeIf(eq, instr->environment()); |
| 3499 __ CompareObjectType(receiver, scratch, scratch, FIRST_SPEC_OBJECT_TYPE); | 3485 __ CompareObjectType(receiver, scratch, scratch, FIRST_SPEC_OBJECT_TYPE); |
| 3500 DeoptimizeIf(lt, instr->environment()); | 3486 DeoptimizeIf(lt, instr->environment()); |
| 3501 __ b(&result_in_receiver); | 3487 __ b(&result_in_receiver); |
| 3502 | 3488 |
| 3503 __ bind(&global_object); | 3489 __ bind(&global_object); |
| 3504 __ ldr(result, GlobalObjectOperand()); | 3490 |
| 3491 __ ldr(result, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 3492 __ ldr(result, ContextOperand(result, Context::GLOBAL_OBJECT_INDEX)); |
| 3505 __ ldr(result, | 3493 __ ldr(result, |
| 3506 FieldMemOperand(result, JSGlobalObject::kGlobalReceiverOffset)); | 3494 FieldMemOperand(result, JSGlobalObject::kGlobalReceiverOffset)); |
| 3507 if (result.is(receiver)) { | 3495 if (result.is(receiver)) { |
| 3508 __ bind(&result_in_receiver); | 3496 __ bind(&result_in_receiver); |
| 3509 } else { | 3497 } else { |
| 3510 Label result_ok; | 3498 Label result_ok; |
| 3511 __ b(&result_ok); | 3499 __ b(&result_ok); |
| 3512 __ bind(&result_in_receiver); | 3500 __ bind(&result_in_receiver); |
| 3513 __ mov(result, receiver); | 3501 __ mov(result, receiver); |
| 3514 __ bind(&result_ok); | 3502 __ bind(&result_ok); |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3934 Register temp1 = ToRegister(instr->temp1()); | 3922 Register temp1 = ToRegister(instr->temp1()); |
| 3935 Register temp2 = ToRegister(instr->temp2()); | 3923 Register temp2 = ToRegister(instr->temp2()); |
| 3936 | 3924 |
| 3937 MathExpGenerator::EmitMathExp( | 3925 MathExpGenerator::EmitMathExp( |
| 3938 masm(), input, result, double_scratch1, double_scratch2, | 3926 masm(), input, result, double_scratch1, double_scratch2, |
| 3939 temp1, temp2, scratch0()); | 3927 temp1, temp2, scratch0()); |
| 3940 } | 3928 } |
| 3941 | 3929 |
| 3942 | 3930 |
| 3943 void LCodeGen::DoMathLog(LMathLog* instr) { | 3931 void LCodeGen::DoMathLog(LMathLog* instr) { |
| 3944 ASSERT(ToDoubleRegister(instr->result()).is(d2)); | 3932 __ PrepareCallCFunction(0, 1, scratch0()); |
| 3945 // Set the context register to a GC-safe fake value. Clobbering it is | 3933 __ SetCallCDoubleArguments(ToDoubleRegister(instr->value())); |
| 3946 // OK because this instruction is marked as a call. | 3934 __ CallCFunction(ExternalReference::math_log_double_function(isolate()), |
| 3947 __ mov(cp, Operand::Zero()); | 3935 0, 1); |
| 3948 TranscendentalCacheStub stub(TranscendentalCache::LOG, | 3936 __ GetCFunctionDoubleResult(ToDoubleRegister(instr->result())); |
| 3949 TranscendentalCacheStub::UNTAGGED); | |
| 3950 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | |
| 3951 } | 3937 } |
| 3952 | 3938 |
| 3953 | 3939 |
| 3954 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { | 3940 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { |
| 3955 ASSERT(ToRegister(instr->context()).is(cp)); | 3941 ASSERT(ToRegister(instr->context()).is(cp)); |
| 3956 ASSERT(ToRegister(instr->function()).is(r1)); | 3942 ASSERT(ToRegister(instr->function()).is(r1)); |
| 3957 ASSERT(instr->HasPointerMap()); | 3943 ASSERT(instr->HasPointerMap()); |
| 3958 | 3944 |
| 3959 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); | 3945 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); |
| 3960 if (known_function.is_null()) { | 3946 if (known_function.is_null()) { |
| (...skipping 1619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5580 EmitBranch(instr, eq); | 5566 EmitBranch(instr, eq); |
| 5581 } | 5567 } |
| 5582 | 5568 |
| 5583 | 5569 |
| 5584 void LCodeGen::EmitIsConstructCall(Register temp1, Register temp2) { | 5570 void LCodeGen::EmitIsConstructCall(Register temp1, Register temp2) { |
| 5585 ASSERT(!temp1.is(temp2)); | 5571 ASSERT(!temp1.is(temp2)); |
| 5586 // Get the frame pointer for the calling frame. | 5572 // Get the frame pointer for the calling frame. |
| 5587 __ ldr(temp1, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 5573 __ ldr(temp1, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
| 5588 | 5574 |
| 5589 // Skip the arguments adaptor frame if it exists. | 5575 // Skip the arguments adaptor frame if it exists. |
| 5590 Label check_frame_marker; | |
| 5591 __ ldr(temp2, MemOperand(temp1, StandardFrameConstants::kContextOffset)); | 5576 __ ldr(temp2, MemOperand(temp1, StandardFrameConstants::kContextOffset)); |
| 5592 __ cmp(temp2, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 5577 __ cmp(temp2, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
| 5593 __ b(ne, &check_frame_marker); | 5578 __ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kCallerFPOffset), eq); |
| 5594 __ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kCallerFPOffset)); | |
| 5595 | 5579 |
| 5596 // Check the marker in the calling frame. | 5580 // Check the marker in the calling frame. |
| 5597 __ bind(&check_frame_marker); | |
| 5598 __ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kMarkerOffset)); | 5581 __ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kMarkerOffset)); |
| 5599 __ cmp(temp1, Operand(Smi::FromInt(StackFrame::CONSTRUCT))); | 5582 __ cmp(temp1, Operand(Smi::FromInt(StackFrame::CONSTRUCT))); |
| 5600 } | 5583 } |
| 5601 | 5584 |
| 5602 | 5585 |
| 5603 void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) { | 5586 void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) { |
| 5604 if (info()->IsStub()) return; | 5587 if (info()->IsStub()) return; |
| 5605 // Ensure that we have enough space after the previous lazy-bailout | 5588 // Ensure that we have enough space after the previous lazy-bailout |
| 5606 // instruction for patching the code here. | 5589 // instruction for patching the code here. |
| 5607 int current_pc = masm()->pc_offset(); | 5590 int current_pc = masm()->pc_offset(); |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5824 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); | 5807 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); |
| 5825 __ ldr(result, FieldMemOperand(scratch, | 5808 __ ldr(result, FieldMemOperand(scratch, |
| 5826 FixedArray::kHeaderSize - kPointerSize)); | 5809 FixedArray::kHeaderSize - kPointerSize)); |
| 5827 __ bind(&done); | 5810 __ bind(&done); |
| 5828 } | 5811 } |
| 5829 | 5812 |
| 5830 | 5813 |
| 5831 #undef __ | 5814 #undef __ |
| 5832 | 5815 |
| 5833 } } // namespace v8::internal | 5816 } } // namespace v8::internal |
| OLD | NEW |