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

Side by Side Diff: src/x64/lithium-codegen-x64.cc

Issue 7795051: Change the x64 optimizing compiler to stop using the fixed context register rsi. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Remove stray edits. Created 9 years, 3 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 for (int i = 0; i < num_parameters; i++) { 209 for (int i = 0; i < num_parameters; i++) {
210 Variable* var = scope()->parameter(i); 210 Variable* var = scope()->parameter(i);
211 if (var->IsContextSlot()) { 211 if (var->IsContextSlot()) {
212 int parameter_offset = StandardFrameConstants::kCallerSPOffset + 212 int parameter_offset = StandardFrameConstants::kCallerSPOffset +
213 (num_parameters - 1 - i) * kPointerSize; 213 (num_parameters - 1 - i) * kPointerSize;
214 // Load parameter from stack. 214 // Load parameter from stack.
215 __ movq(rax, Operand(rbp, parameter_offset)); 215 __ movq(rax, Operand(rbp, parameter_offset));
216 // Store it in the context. 216 // Store it in the context.
217 int context_offset = Context::SlotOffset(var->index()); 217 int context_offset = Context::SlotOffset(var->index());
218 __ movq(Operand(rsi, context_offset), rax); 218 __ movq(Operand(rsi, context_offset), rax);
219 // Update the write barrier. This clobbers all involved 219 // Update the write barrier.
220 // registers, so we have use a third register to avoid 220 __ RecordWrite(rsi, context_offset, rax, rbx);
221 // clobbering rsi.
222 __ movq(rcx, rsi);
223 __ RecordWrite(rcx, context_offset, rax, rbx);
224 } 221 }
225 } 222 }
226 Comment(";;; End allocate local context"); 223 Comment(";;; End allocate local context");
227 } 224 }
228 225
229 // Trace the call. 226 // Trace the call.
230 if (FLAG_trace) { 227 if (FLAG_trace) {
231 __ CallRuntime(Runtime::kTraceEnter, 0); 228 __ CallRuntime(Runtime::kTraceEnter, 0);
232 } 229 }
233 return !is_aborted(); 230 return !is_aborted();
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 LPointerMap* pointers = instr->pointer_map(); 501 LPointerMap* pointers = instr->pointer_map();
505 RecordPosition(pointers->position()); 502 RecordPosition(pointers->position());
506 503
507 __ CallRuntime(function, num_arguments); 504 __ CallRuntime(function, num_arguments);
508 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT, 0); 505 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT, 0);
509 } 506 }
510 507
511 508
512 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id, 509 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id,
513 int argc, 510 int argc,
514 LInstruction* instr) { 511 LInstruction* instr,
515 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 512 LOperand* context) {
513 ASSERT(context->IsRegister() || context->IsStackSlot());
514 if (context->IsRegister()) {
515 if (!ToRegister(context).is(rsi)) {
516 __ movq(rsi, ToRegister(context));
517 }
518 } else {
519 // Context is stack slot.
520 __ movq(rsi, ToOperand(context));
521 }
522
516 __ CallRuntimeSaveDoubles(id); 523 __ CallRuntimeSaveDoubles(id);
517 RecordSafepointWithRegisters( 524 RecordSafepointWithRegisters(
518 instr->pointer_map(), argc, Safepoint::kNoDeoptimizationIndex); 525 instr->pointer_map(), argc, Safepoint::kNoDeoptimizationIndex);
519 } 526 }
520 527
521 528
522 void LCodeGen::RegisterLazyDeoptimization(LInstruction* instr, 529 void LCodeGen::RegisterLazyDeoptimization(LInstruction* instr,
523 SafepointMode safepoint_mode, 530 SafepointMode safepoint_mode,
524 int argc) { 531 int argc) {
525 // Create the environment to bailout to. If the call has side effects 532 // Create the environment to bailout to. If the call has side effects
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 Safepoint safepoint = safepoints_.DefineSafepoint(masm(), 678 Safepoint safepoint = safepoints_.DefineSafepoint(masm(),
672 kind, arguments, deoptimization_index); 679 kind, arguments, deoptimization_index);
673 for (int i = 0; i < operands->length(); i++) { 680 for (int i = 0; i < operands->length(); i++) {
674 LOperand* pointer = operands->at(i); 681 LOperand* pointer = operands->at(i);
675 if (pointer->IsStackSlot()) { 682 if (pointer->IsStackSlot()) {
676 safepoint.DefinePointerSlot(pointer->index()); 683 safepoint.DefinePointerSlot(pointer->index());
677 } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) { 684 } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) {
678 safepoint.DefinePointerRegister(ToRegister(pointer)); 685 safepoint.DefinePointerRegister(ToRegister(pointer));
679 } 686 }
680 } 687 }
681 if (kind & Safepoint::kWithRegisters) {
682 // Register rsi always contains a pointer to the context.
683 safepoint.DefinePointerRegister(rsi);
684 }
685 } 688 }
686 689
687 690
688 void LCodeGen::RecordSafepoint(LPointerMap* pointers, 691 void LCodeGen::RecordSafepoint(LPointerMap* pointers,
689 int deoptimization_index) { 692 int deoptimization_index) {
690 RecordSafepoint(pointers, Safepoint::kSimple, 0, deoptimization_index); 693 RecordSafepoint(pointers, Safepoint::kSimple, 0, deoptimization_index);
691 } 694 }
692 695
693 696
694 void LCodeGen::RecordSafepoint(int deoptimization_index) { 697 void LCodeGen::RecordSafepoint(int deoptimization_index) {
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after
1255 1258
1256 1259
1257 void LCodeGen::DoBitNotI(LBitNotI* instr) { 1260 void LCodeGen::DoBitNotI(LBitNotI* instr) {
1258 LOperand* input = instr->InputAt(0); 1261 LOperand* input = instr->InputAt(0);
1259 ASSERT(input->Equals(instr->result())); 1262 ASSERT(input->Equals(instr->result()));
1260 __ not_(ToRegister(input)); 1263 __ not_(ToRegister(input));
1261 } 1264 }
1262 1265
1263 1266
1264 void LCodeGen::DoThrow(LThrow* instr) { 1267 void LCodeGen::DoThrow(LThrow* instr) {
1265 __ push(ToRegister(instr->InputAt(0))); 1268 __ push(ToRegister(instr->value()));
1266 CallRuntime(Runtime::kThrow, 1, instr); 1269 CallRuntime(Runtime::kThrow, 1, instr);
1267 1270
1268 if (FLAG_debug_code) { 1271 if (FLAG_debug_code) {
1269 Comment("Unreachable code."); 1272 Comment("Unreachable code.");
1270 __ int3(); 1273 __ int3();
1271 } 1274 }
1272 } 1275 }
1273 1276
1274 1277
1275 void LCodeGen::DoAddI(LAddI* instr) { 1278 void LCodeGen::DoAddI(LAddI* instr) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1311 case Token::DIV: 1314 case Token::DIV:
1312 __ divsd(left, right); 1315 __ divsd(left, right);
1313 break; 1316 break;
1314 case Token::MOD: 1317 case Token::MOD:
1315 __ PrepareCallCFunction(2); 1318 __ PrepareCallCFunction(2);
1316 __ movaps(xmm0, left); 1319 __ movaps(xmm0, left);
1317 ASSERT(right.is(xmm1)); 1320 ASSERT(right.is(xmm1));
1318 __ CallCFunction( 1321 __ CallCFunction(
1319 ExternalReference::double_fp_operation(Token::MOD, isolate()), 2); 1322 ExternalReference::double_fp_operation(Token::MOD, isolate()), 2);
1320 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 1323 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
1324 __ movq(rsi, Immediate(0));
1321 __ movaps(result, xmm0); 1325 __ movaps(result, xmm0);
1322 break; 1326 break;
1323 default: 1327 default:
1324 UNREACHABLE(); 1328 UNREACHABLE();
1325 break; 1329 break;
1326 } 1330 }
1327 } 1331 }
1328 1332
1329 1333
1330 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { 1334 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
1331 ASSERT(ToRegister(instr->InputAt(0)).is(rdx)); 1335 ASSERT(ToRegister(instr->context()).is(rsi));
1332 ASSERT(ToRegister(instr->InputAt(1)).is(rax)); 1336 ASSERT(ToRegister(instr->left()).is(rdx));
1337 ASSERT(ToRegister(instr->right()).is(rax));
1333 ASSERT(ToRegister(instr->result()).is(rax)); 1338 ASSERT(ToRegister(instr->result()).is(rax));
1334 1339
1335 BinaryOpStub stub(instr->op(), NO_OVERWRITE); 1340 BinaryOpStub stub(instr->op(), NO_OVERWRITE);
1336 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 1341 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1337 __ nop(); // Signals no inlined code. 1342 __ nop(); // Signals no inlined code.
1338 } 1343 }
1339 1344
1340 1345
1341 int LCodeGen::GetNextEmittedBlock(int block) { 1346 int LCodeGen::GetNextEmittedBlock(int block) {
1342 for (int i = block + 1; i < graph()->blocks()->length(); ++i) { 1347 for (int i = block + 1; i < graph()->blocks()->length(); ++i) {
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
1822 int true_block = instr->true_block_id(); 1827 int true_block = instr->true_block_id();
1823 int false_block = instr->false_block_id(); 1828 int false_block = instr->false_block_id();
1824 1829
1825 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map()); 1830 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map());
1826 EmitBranch(true_block, false_block, equal); 1831 EmitBranch(true_block, false_block, equal);
1827 } 1832 }
1828 1833
1829 1834
1830 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { 1835 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
1831 InstanceofStub stub(InstanceofStub::kNoFlags); 1836 InstanceofStub stub(InstanceofStub::kNoFlags);
1832 __ push(ToRegister(instr->InputAt(0))); 1837 __ push(ToRegister(instr->left()));
1833 __ push(ToRegister(instr->InputAt(1))); 1838 __ push(ToRegister(instr->right()));
1834 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 1839 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1835 Label true_value, done; 1840 Label true_value, done;
1836 __ testq(rax, rax); 1841 __ testq(rax, rax);
1837 __ j(zero, &true_value, Label::kNear); 1842 __ j(zero, &true_value, Label::kNear);
1838 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex); 1843 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex);
1839 __ jmp(&done, Label::kNear); 1844 __ jmp(&done, Label::kNear);
1840 __ bind(&true_value); 1845 __ bind(&true_value);
1841 __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex); 1846 __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex);
1842 __ bind(&done); 1847 __ bind(&done);
1843 } 1848 }
(...skipping 14 matching lines...) Expand all
1858 private: 1863 private:
1859 LInstanceOfKnownGlobal* instr_; 1864 LInstanceOfKnownGlobal* instr_;
1860 Label map_check_; 1865 Label map_check_;
1861 }; 1866 };
1862 1867
1863 1868
1864 DeferredInstanceOfKnownGlobal* deferred; 1869 DeferredInstanceOfKnownGlobal* deferred;
1865 deferred = new DeferredInstanceOfKnownGlobal(this, instr); 1870 deferred = new DeferredInstanceOfKnownGlobal(this, instr);
1866 1871
1867 Label done, false_result; 1872 Label done, false_result;
1868 Register object = ToRegister(instr->InputAt(0)); 1873 Register object = ToRegister(instr->value());
1869 1874
1870 // A Smi is not an instance of anything. 1875 // A Smi is not an instance of anything.
1871 __ JumpIfSmi(object, &false_result); 1876 __ JumpIfSmi(object, &false_result);
1872 1877
1873 // This is the inlined call site instanceof cache. The two occurences of the 1878 // This is the inlined call site instanceof cache. The two occurences of the
1874 // hole value will be patched to the last map/result pair generated by the 1879 // hole value will be patched to the last map/result pair generated by the
1875 // instanceof stub. 1880 // instanceof stub.
1876 Label cache_miss; 1881 Label cache_miss;
1877 // Use a temp register to avoid memory operands with variable lengths. 1882 // Use a temp register to avoid memory operands with variable lengths.
1878 Register map = ToRegister(instr->TempAt(0)); 1883 Register map = ToRegister(instr->TempAt(0));
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1910 1915
1911 1916
1912 void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, 1917 void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
1913 Label* map_check) { 1918 Label* map_check) {
1914 { 1919 {
1915 PushSafepointRegistersScope scope(this); 1920 PushSafepointRegistersScope scope(this);
1916 InstanceofStub::Flags flags = static_cast<InstanceofStub::Flags>( 1921 InstanceofStub::Flags flags = static_cast<InstanceofStub::Flags>(
1917 InstanceofStub::kNoFlags | InstanceofStub::kCallSiteInlineCheck); 1922 InstanceofStub::kNoFlags | InstanceofStub::kCallSiteInlineCheck);
1918 InstanceofStub stub(flags); 1923 InstanceofStub stub(flags);
1919 1924
1920 __ push(ToRegister(instr->InputAt(0))); 1925 __ push(ToRegister(instr->value()));
1921 __ Push(instr->function()); 1926 __ Push(instr->function());
1922 1927
1923 static const int kAdditionalDelta = 10; 1928 static const int kAdditionalDelta = 10;
1924 int delta = 1929 int delta =
1925 masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; 1930 masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
1926 ASSERT(delta >= 0); 1931 ASSERT(delta >= 0);
1927 __ push_imm32(delta); 1932 __ push_imm32(delta);
1928 1933
1929 // We are pushing three values on the stack but recording a 1934 // We are pushing three values on the stack but recording a
1930 // safepoint with two arguments because stub is going to 1935 // safepoint with two arguments because stub is going to
(...skipping 15 matching lines...) Expand all
1946 __ j(not_zero, &load_false); 1951 __ j(not_zero, &load_false);
1947 __ LoadRoot(rax, Heap::kTrueValueRootIndex); 1952 __ LoadRoot(rax, Heap::kTrueValueRootIndex);
1948 __ jmp(&done); 1953 __ jmp(&done);
1949 __ bind(&load_false); 1954 __ bind(&load_false);
1950 __ LoadRoot(rax, Heap::kFalseValueRootIndex); 1955 __ LoadRoot(rax, Heap::kFalseValueRootIndex);
1951 __ bind(&done); 1956 __ bind(&done);
1952 } 1957 }
1953 1958
1954 1959
1955 void LCodeGen::DoCmpT(LCmpT* instr) { 1960 void LCodeGen::DoCmpT(LCmpT* instr) {
1961 ASSERT(ToRegister(instr->context()).is(rsi));
1962 ASSERT((ToRegister(instr->left()).is(rax) &&
1963 ToRegister(instr->right()).is(rdx)) ||
1964 (ToRegister(instr->left()).is(rdx) &&
1965 ToRegister(instr->right()).is(rax)));
1966 ASSERT(ToRegister(instr->result()).is(rax));
1956 Token::Value op = instr->op(); 1967 Token::Value op = instr->op();
1957 1968
1958 Handle<Code> ic = CompareIC::GetUninitialized(op); 1969 Handle<Code> ic = CompareIC::GetUninitialized(op);
1959 CallCode(ic, RelocInfo::CODE_TARGET, instr); 1970 CallCode(ic, RelocInfo::CODE_TARGET, instr);
1960 1971
1961 Condition condition = TokenToCondition(op, false); 1972 Condition condition = TokenToCondition(op, false);
1962 if (op == Token::GT || op == Token::LTE) { 1973 if (op == Token::GT || op == Token::LTE) {
1963 condition = ReverseCondition(condition); 1974 condition = ReverseCondition(condition);
1964 } 1975 }
1965 Label true_value, done; 1976 Label true_value, done;
(...skipping 30 matching lines...) Expand all
1996 __ movq(result, Operand(result, 0)); 2007 __ movq(result, Operand(result, 0));
1997 } 2008 }
1998 if (instr->hydrogen()->check_hole_value()) { 2009 if (instr->hydrogen()->check_hole_value()) {
1999 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); 2010 __ CompareRoot(result, Heap::kTheHoleValueRootIndex);
2000 DeoptimizeIf(equal, instr->environment()); 2011 DeoptimizeIf(equal, instr->environment());
2001 } 2012 }
2002 } 2013 }
2003 2014
2004 2015
2005 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { 2016 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
2017 ASSERT(ToRegister(instr->context()).is(rsi));
2006 ASSERT(ToRegister(instr->global_object()).is(rax)); 2018 ASSERT(ToRegister(instr->global_object()).is(rax));
2007 ASSERT(ToRegister(instr->result()).is(rax)); 2019 ASSERT(ToRegister(instr->result()).is(rax));
2008 2020
2009 __ Move(rcx, instr->name()); 2021 __ Move(rcx, instr->name());
2010 RelocInfo::Mode mode = instr->for_typeof() ? RelocInfo::CODE_TARGET : 2022 RelocInfo::Mode mode = instr->for_typeof() ? RelocInfo::CODE_TARGET :
2011 RelocInfo::CODE_TARGET_CONTEXT; 2023 RelocInfo::CODE_TARGET_CONTEXT;
2012 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 2024 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
2013 CallCode(ic, mode, instr); 2025 CallCode(ic, mode, instr);
2014 } 2026 }
2015 2027
2016 2028
2017 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { 2029 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
2018 Register value = ToRegister(instr->InputAt(0)); 2030 Register value = ToRegister(instr->value());
2019 Register temp = ToRegister(instr->TempAt(0)); 2031 Register temp = ToRegister(instr->TempAt(0));
2020 ASSERT(!value.is(temp)); 2032 ASSERT(!value.is(temp));
2021 bool check_hole = instr->hydrogen()->check_hole_value(); 2033 bool check_hole = instr->hydrogen()->check_hole_value();
2022 if (!check_hole && value.is(rax)) { 2034 if (!check_hole && value.is(rax)) {
2023 __ store_rax(instr->hydrogen()->cell().location(), 2035 __ store_rax(instr->hydrogen()->cell().location(),
2024 RelocInfo::GLOBAL_PROPERTY_CELL); 2036 RelocInfo::GLOBAL_PROPERTY_CELL);
2025 return; 2037 return;
2026 } 2038 }
2027 // If the cell we are storing to contains the hole it could have 2039 // If the cell we are storing to contains the hole it could have
2028 // been deleted from the property dictionary. In that case, we need 2040 // been deleted from the property dictionary. In that case, we need
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
2471 Condition is_smi = __ CheckSmi(receiver); 2483 Condition is_smi = __ CheckSmi(receiver);
2472 DeoptimizeIf(is_smi, instr->environment()); 2484 DeoptimizeIf(is_smi, instr->environment());
2473 __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, kScratchRegister); 2485 __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, kScratchRegister);
2474 DeoptimizeIf(below, instr->environment()); 2486 DeoptimizeIf(below, instr->environment());
2475 __ jmp(&receiver_ok, Label::kNear); 2487 __ jmp(&receiver_ok, Label::kNear);
2476 2488
2477 __ bind(&global_object); 2489 __ bind(&global_object);
2478 // TODO(kmillikin): We have a hydrogen value for the global object. See 2490 // TODO(kmillikin): We have a hydrogen value for the global object. See
2479 // if it's better to use it than to explicitly fetch it from the context 2491 // if it's better to use it than to explicitly fetch it from the context
2480 // here. 2492 // here.
2481 __ movq(receiver, ContextOperand(rsi, Context::GLOBAL_INDEX)); 2493 __ movq(receiver, Operand(rbp, StandardFrameConstants::kContextOffset));
2494 __ movq(receiver, ContextOperand(receiver, Context::GLOBAL_INDEX));
2482 __ movq(receiver, 2495 __ movq(receiver,
2483 FieldOperand(receiver, JSGlobalObject::kGlobalReceiverOffset)); 2496 FieldOperand(receiver, JSGlobalObject::kGlobalReceiverOffset));
2484 __ bind(&receiver_ok); 2497 __ bind(&receiver_ok);
2485 2498
2486 // Copy the arguments to this function possibly from the 2499 // Copy the arguments to this function possibly from the
2487 // adaptor frame below it. 2500 // adaptor frame below it.
2488 const uint32_t kArgumentsLimit = 1 * KB; 2501 const uint32_t kArgumentsLimit = 1 * KB;
2489 __ cmpq(length, Immediate(kArgumentsLimit)); 2502 __ cmpq(length, Immediate(kArgumentsLimit));
2490 DeoptimizeIf(above, instr->environment()); 2503 DeoptimizeIf(above, instr->environment());
2491 2504
(...skipping 18 matching lines...) Expand all
2510 LEnvironment* env = instr->deoptimization_environment(); 2523 LEnvironment* env = instr->deoptimization_environment();
2511 RecordPosition(pointers->position()); 2524 RecordPosition(pointers->position());
2512 RegisterEnvironmentForDeoptimization(env); 2525 RegisterEnvironmentForDeoptimization(env);
2513 SafepointGenerator safepoint_generator(this, 2526 SafepointGenerator safepoint_generator(this,
2514 pointers, 2527 pointers,
2515 env->deoptimization_index()); 2528 env->deoptimization_index());
2516 v8::internal::ParameterCount actual(rax); 2529 v8::internal::ParameterCount actual(rax);
2517 __ InvokeFunction(function, actual, CALL_FUNCTION, 2530 __ InvokeFunction(function, actual, CALL_FUNCTION,
2518 safepoint_generator, CALL_AS_METHOD); 2531 safepoint_generator, CALL_AS_METHOD);
2519 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2532 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2533 __ movq(rsi, Immediate(0));
2520 } 2534 }
2521 2535
2522 2536
2523 void LCodeGen::DoPushArgument(LPushArgument* instr) { 2537 void LCodeGen::DoPushArgument(LPushArgument* instr) {
2524 LOperand* argument = instr->InputAt(0); 2538 LOperand* argument = instr->InputAt(0);
2525 EmitPushTaggedOperand(argument); 2539 EmitPushTaggedOperand(argument);
2526 } 2540 }
2527 2541
2528 2542
2529 void LCodeGen::DoThisFunction(LThisFunction* instr) { 2543 void LCodeGen::DoThisFunction(LThisFunction* instr) {
2530 Register result = ToRegister(instr->result()); 2544 Register result = ToRegister(instr->result());
2531 __ movq(result, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 2545 __ movq(result, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
2532 } 2546 }
2533 2547
2534 2548
2535 void LCodeGen::DoContext(LContext* instr) { 2549 void LCodeGen::DoContext(LContext* instr) {
2536 Register result = ToRegister(instr->result()); 2550 Register result = ToRegister(instr->result());
2537 __ movq(result, rsi); 2551 __ movq(result, Operand(rbp, StandardFrameConstants::kContextOffset));
2538 } 2552 }
2539 2553
2540 2554
2541 void LCodeGen::DoOuterContext(LOuterContext* instr) { 2555 void LCodeGen::DoOuterContext(LOuterContext* instr) {
2542 Register context = ToRegister(instr->context()); 2556 Register context = ToRegister(instr->context());
2543 Register result = ToRegister(instr->result()); 2557 Register result = ToRegister(instr->result());
2544 __ movq(result, 2558 __ movq(result,
2545 Operand(context, Context::SlotOffset(Context::PREVIOUS_INDEX))); 2559 Operand(context, Context::SlotOffset(Context::PREVIOUS_INDEX)));
2546 } 2560 }
2547 2561
2548 2562
2549 void LCodeGen::DoGlobalObject(LGlobalObject* instr) { 2563 void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
2564 Register context = ToRegister(instr->context());
2550 Register result = ToRegister(instr->result()); 2565 Register result = ToRegister(instr->result());
2551 __ movq(result, GlobalObjectOperand()); 2566 __ movq(result,
2567 Operand(context, Context::SlotOffset(Context::GLOBAL_INDEX)));
2552 } 2568 }
2553 2569
2554 2570
2555 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { 2571 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) {
2556 Register global = ToRegister(instr->global()); 2572 Register global = ToRegister(instr->global());
2557 Register result = ToRegister(instr->result()); 2573 Register result = ToRegister(instr->result());
2558 __ movq(result, FieldOperand(global, GlobalObject::kGlobalReceiverOffset)); 2574 __ movq(result, FieldOperand(global, GlobalObject::kGlobalReceiverOffset));
2559 } 2575 }
2560 2576
2561 2577
2562 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, 2578 void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
2563 int arity, 2579 int arity,
2564 LInstruction* instr, 2580 LInstruction* instr,
2565 CallKind call_kind) { 2581 CallKind call_kind) {
2566 // Change context if needed. 2582 // Change context if needed.
2567 bool change_context = 2583 bool change_context =
2568 (info()->closure()->context() != function->context()) || 2584 (info()->closure()->context() != function->context()) ||
2569 scope()->contains_with() || 2585 scope()->contains_with() ||
2570 (scope()->num_heap_slots() > 0); 2586 (scope()->num_heap_slots() > 0);
2571 if (change_context) { 2587 if (change_context) {
2572 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 2588 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
2589 } else {
2590 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2573 } 2591 }
2574 2592
2575 // Set rax to arguments count if adaption is not needed. Assumes that rax 2593 // Set rax to arguments count if adaption is not needed. Assumes that rax
2576 // is available to write to at this point. 2594 // is available to write to at this point.
2577 if (!function->NeedsArgumentsAdaption()) { 2595 if (!function->NeedsArgumentsAdaption()) {
2578 __ Set(rax, arity); 2596 __ Set(rax, arity);
2579 } 2597 }
2580 2598
2581 LPointerMap* pointers = instr->pointer_map(); 2599 LPointerMap* pointers = instr->pointer_map();
2582 RecordPosition(pointers->position()); 2600 RecordPosition(pointers->position());
2583 2601
2584 // Invoke function. 2602 // Invoke function.
2585 __ SetCallKind(rcx, call_kind); 2603 __ SetCallKind(rcx, call_kind);
2586 if (*function == *info()->closure()) { 2604 if (*function == *info()->closure()) {
2587 __ CallSelf(); 2605 __ CallSelf();
2588 } else { 2606 } else {
2589 __ call(FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 2607 __ call(FieldOperand(rdi, JSFunction::kCodeEntryOffset));
2590 } 2608 }
2591 2609
2592 // Setup deoptimization. 2610 // Setup deoptimization.
2593 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT, 0); 2611 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT, 0);
2594 2612
2595 // Restore context. 2613 // Restore context.
2596 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2614 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2615 __ movq(rsi, Immediate(0));
2597 } 2616 }
2598 2617
2599 2618
2600 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { 2619 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
2601 ASSERT(ToRegister(instr->result()).is(rax)); 2620 ASSERT(ToRegister(instr->result()).is(rax));
2602 __ Move(rdi, instr->function()); 2621 __ Move(rdi, instr->function());
2603 CallKnownFunction(instr->function(), 2622 CallKnownFunction(instr->function(),
2604 instr->arity(), 2623 instr->arity(),
2605 instr, 2624 instr,
2606 CALL_AS_METHOD); 2625 CALL_AS_METHOD);
2607 } 2626 }
2608 2627
2609 2628
2610 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { 2629 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) {
2611 Register input_reg = ToRegister(instr->InputAt(0)); 2630 Register input_reg = ToRegister(instr->value());
2612 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), 2631 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
2613 Heap::kHeapNumberMapRootIndex); 2632 Heap::kHeapNumberMapRootIndex);
2614 DeoptimizeIf(not_equal, instr->environment()); 2633 DeoptimizeIf(not_equal, instr->environment());
2615 2634
2616 Label done; 2635 Label done;
2617 Register tmp = input_reg.is(rax) ? rcx : rax; 2636 Register tmp = input_reg.is(rax) ? rcx : rax;
2618 Register tmp2 = tmp.is(rcx) ? rdx : input_reg.is(rcx) ? rdx : rcx; 2637 Register tmp2 = tmp.is(rcx) ? rdx : input_reg.is(rcx) ? rdx : rcx;
2619 2638
2620 // Preserve the value of all registers. 2639 // Preserve the value of all registers.
2621 PushSafepointRegistersScope scope(this); 2640 PushSafepointRegistersScope scope(this);
(...skipping 10 matching lines...) Expand all
2632 2651
2633 __ bind(&negative); 2652 __ bind(&negative);
2634 2653
2635 Label allocated, slow; 2654 Label allocated, slow;
2636 __ AllocateHeapNumber(tmp, tmp2, &slow); 2655 __ AllocateHeapNumber(tmp, tmp2, &slow);
2637 __ jmp(&allocated); 2656 __ jmp(&allocated);
2638 2657
2639 // Slow case: Call the runtime system to do the number allocation. 2658 // Slow case: Call the runtime system to do the number allocation.
2640 __ bind(&slow); 2659 __ bind(&slow);
2641 2660
2642 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); 2661 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr,
2662 instr->context());
2643 // Set the pointer to the new heap number in tmp. 2663 // Set the pointer to the new heap number in tmp.
2644 if (!tmp.is(rax)) { 2664 if (!tmp.is(rax)) {
2645 __ movq(tmp, rax); 2665 __ movq(tmp, rax);
2646 } 2666 }
2647 2667
2648 // Restore input_reg after call to runtime. 2668 // Restore input_reg after call to runtime.
2649 __ LoadFromSafepointRegisterSlot(input_reg, input_reg); 2669 __ LoadFromSafepointRegisterSlot(input_reg, input_reg);
2650 2670
2651 __ bind(&allocated); 2671 __ bind(&allocated);
2652 __ movq(tmp2, FieldOperand(input_reg, HeapNumber::kValueOffset)); 2672 __ movq(tmp2, FieldOperand(input_reg, HeapNumber::kValueOffset));
2653 __ shl(tmp2, Immediate(1)); 2673 __ shl(tmp2, Immediate(1));
2654 __ shr(tmp2, Immediate(1)); 2674 __ shr(tmp2, Immediate(1));
2655 __ movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2); 2675 __ movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2);
2656 __ StoreToSafepointRegisterSlot(input_reg, tmp); 2676 __ StoreToSafepointRegisterSlot(input_reg, tmp);
2657 2677
2658 __ bind(&done); 2678 __ bind(&done);
2659 } 2679 }
2660 2680
2661 2681
2662 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { 2682 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) {
2663 Register input_reg = ToRegister(instr->InputAt(0)); 2683 Register input_reg = ToRegister(instr->value());
2664 __ testl(input_reg, input_reg); 2684 __ testl(input_reg, input_reg);
2665 Label is_positive; 2685 Label is_positive;
2666 __ j(not_sign, &is_positive); 2686 __ j(not_sign, &is_positive);
2667 __ negl(input_reg); // Sets flags. 2687 __ negl(input_reg); // Sets flags.
2668 DeoptimizeIf(negative, instr->environment()); 2688 DeoptimizeIf(negative, instr->environment());
2669 __ bind(&is_positive); 2689 __ bind(&is_positive);
2670 } 2690 }
2671 2691
2672 2692
2673 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { 2693 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
2674 // Class for deferred case. 2694 // Class for deferred case.
2675 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 2695 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
2676 public: 2696 public:
2677 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, 2697 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen,
2678 LUnaryMathOperation* instr) 2698 LUnaryMathOperation* instr)
2679 : LDeferredCode(codegen), instr_(instr) { } 2699 : LDeferredCode(codegen), instr_(instr) { }
2680 virtual void Generate() { 2700 virtual void Generate() {
2681 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 2701 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
2682 } 2702 }
2683 private: 2703 private:
2684 LUnaryMathOperation* instr_; 2704 LUnaryMathOperation* instr_;
2685 }; 2705 };
2686 2706
2687 ASSERT(instr->InputAt(0)->Equals(instr->result())); 2707 ASSERT(instr->value()->Equals(instr->result()));
2688 Representation r = instr->hydrogen()->value()->representation(); 2708 Representation r = instr->hydrogen()->value()->representation();
2689 2709
2690 if (r.IsDouble()) { 2710 if (r.IsDouble()) {
2691 XMMRegister scratch = xmm0; 2711 XMMRegister scratch = xmm0;
2692 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 2712 XMMRegister input_reg = ToDoubleRegister(instr->value());
2693 __ xorps(scratch, scratch); 2713 __ xorps(scratch, scratch);
2694 __ subsd(scratch, input_reg); 2714 __ subsd(scratch, input_reg);
2695 __ andpd(input_reg, scratch); 2715 __ andpd(input_reg, scratch);
2696 } else if (r.IsInteger32()) { 2716 } else if (r.IsInteger32()) {
2697 EmitIntegerMathAbs(instr); 2717 EmitIntegerMathAbs(instr);
2698 } else { // Tagged case. 2718 } else { // Tagged case.
2699 DeferredMathAbsTaggedHeapNumber* deferred = 2719 DeferredMathAbsTaggedHeapNumber* deferred =
2700 new DeferredMathAbsTaggedHeapNumber(this, instr); 2720 new DeferredMathAbsTaggedHeapNumber(this, instr);
2701 Register input_reg = ToRegister(instr->InputAt(0)); 2721 Register input_reg = ToRegister(instr->value());
2702 // Smi check. 2722 // Smi check.
2703 __ JumpIfNotSmi(input_reg, deferred->entry()); 2723 __ JumpIfNotSmi(input_reg, deferred->entry());
2704 __ SmiToInteger32(input_reg, input_reg); 2724 __ SmiToInteger32(input_reg, input_reg);
2705 EmitIntegerMathAbs(instr); 2725 EmitIntegerMathAbs(instr);
2706 __ Integer32ToSmi(input_reg, input_reg); 2726 __ Integer32ToSmi(input_reg, input_reg);
2707 __ bind(deferred->exit()); 2727 __ bind(deferred->exit());
2708 } 2728 }
2709 } 2729 }
2710 2730
2711 2731
2712 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { 2732 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
2713 XMMRegister xmm_scratch = xmm0; 2733 XMMRegister xmm_scratch = xmm0;
2714 Register output_reg = ToRegister(instr->result()); 2734 Register output_reg = ToRegister(instr->result());
2715 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 2735 XMMRegister input_reg = ToDoubleRegister(instr->value());
2716 Label done; 2736 Label done;
2717 2737
2718 if (CpuFeatures::IsSupported(SSE4_1)) { 2738 if (CpuFeatures::IsSupported(SSE4_1)) {
2719 CpuFeatures::Scope scope(SSE4_1); 2739 CpuFeatures::Scope scope(SSE4_1);
2720 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 2740 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
2721 // Deoptimize if minus zero. 2741 // Deoptimize if minus zero.
2722 __ movq(output_reg, input_reg); 2742 __ movq(output_reg, input_reg);
2723 __ subq(output_reg, Immediate(1)); 2743 __ subq(output_reg, Immediate(1));
2724 DeoptimizeIf(overflow, instr->environment()); 2744 DeoptimizeIf(overflow, instr->environment());
2725 } 2745 }
(...skipping 25 matching lines...) Expand all
2751 __ cmpl(output_reg, Immediate(0x80000000)); 2771 __ cmpl(output_reg, Immediate(0x80000000));
2752 DeoptimizeIf(equal, instr->environment()); 2772 DeoptimizeIf(equal, instr->environment());
2753 } 2773 }
2754 __ bind(&done); 2774 __ bind(&done);
2755 } 2775 }
2756 2776
2757 2777
2758 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { 2778 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
2759 const XMMRegister xmm_scratch = xmm0; 2779 const XMMRegister xmm_scratch = xmm0;
2760 Register output_reg = ToRegister(instr->result()); 2780 Register output_reg = ToRegister(instr->result());
2761 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 2781 XMMRegister input_reg = ToDoubleRegister(instr->value());
2762 2782
2763 Label done; 2783 Label done;
2764 // xmm_scratch = 0.5 2784 // xmm_scratch = 0.5
2765 __ movq(kScratchRegister, V8_INT64_C(0x3FE0000000000000), RelocInfo::NONE); 2785 __ movq(kScratchRegister, V8_INT64_C(0x3FE0000000000000), RelocInfo::NONE);
2766 __ movq(xmm_scratch, kScratchRegister); 2786 __ movq(xmm_scratch, kScratchRegister);
2767 Label below_half; 2787 Label below_half;
2768 __ ucomisd(xmm_scratch, input_reg); 2788 __ ucomisd(xmm_scratch, input_reg);
2769 // If input_reg is NaN, this doesn't jump. 2789 // If input_reg is NaN, this doesn't jump.
2770 __ j(above, &below_half, Label::kNear); 2790 __ j(above, &below_half, Label::kNear);
2771 // input = input + 0.5 2791 // input = input + 0.5
(...skipping 24 matching lines...) Expand all
2796 __ ucomisd(input_reg, xmm_scratch); 2816 __ ucomisd(input_reg, xmm_scratch);
2797 DeoptimizeIf(below, instr->environment()); 2817 DeoptimizeIf(below, instr->environment());
2798 } 2818 }
2799 __ xorl(output_reg, output_reg); 2819 __ xorl(output_reg, output_reg);
2800 2820
2801 __ bind(&done); 2821 __ bind(&done);
2802 } 2822 }
2803 2823
2804 2824
2805 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 2825 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
2806 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 2826 XMMRegister input_reg = ToDoubleRegister(instr->value());
2807 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 2827 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
2808 __ sqrtsd(input_reg, input_reg); 2828 __ sqrtsd(input_reg, input_reg);
2809 } 2829 }
2810 2830
2811 2831
2812 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { 2832 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
2813 XMMRegister xmm_scratch = xmm0; 2833 XMMRegister xmm_scratch = xmm0;
2814 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); 2834 XMMRegister input_reg = ToDoubleRegister(instr->value());
2815 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 2835 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
2816 __ xorps(xmm_scratch, xmm_scratch); 2836 __ xorps(xmm_scratch, xmm_scratch);
2817 __ addsd(input_reg, xmm_scratch); // Convert -0 to +0. 2837 __ addsd(input_reg, xmm_scratch); // Convert -0 to +0.
2818 __ sqrtsd(input_reg, input_reg); 2838 __ sqrtsd(input_reg, input_reg);
2819 } 2839 }
2820 2840
2821 2841
2822 void LCodeGen::DoPower(LPower* instr) { 2842 void LCodeGen::DoPower(LPower* instr) {
2823 LOperand* left = instr->InputAt(0); 2843 LOperand* left = instr->InputAt(0);
2824 XMMRegister left_reg = ToDoubleRegister(left); 2844 XMMRegister left_reg = ToDoubleRegister(left);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2865 // Move arguments to correct registers xmm0 and xmm1. 2885 // Move arguments to correct registers xmm0 and xmm1.
2866 __ movaps(xmm0, left_reg); 2886 __ movaps(xmm0, left_reg);
2867 // Right argument is already in xmm1. 2887 // Right argument is already in xmm1.
2868 __ CallCFunction( 2888 __ CallCFunction(
2869 ExternalReference::power_double_double_function(isolate()), 2); 2889 ExternalReference::power_double_double_function(isolate()), 2);
2870 } 2890 }
2871 // Return value is in xmm0. 2891 // Return value is in xmm0.
2872 __ movaps(result_reg, xmm0); 2892 __ movaps(result_reg, xmm0);
2873 // Restore context register. 2893 // Restore context register.
2874 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2894 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2895 __ movq(rsi, Immediate(0));
2875 } 2896 }
2876 2897
2877 2898
2878 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { 2899 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
2879 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); 2900 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
2880 TranscendentalCacheStub stub(TranscendentalCache::LOG, 2901 TranscendentalCacheStub stub(TranscendentalCache::LOG,
2881 TranscendentalCacheStub::UNTAGGED); 2902 TranscendentalCacheStub::UNTAGGED);
2882 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 2903 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2883 } 2904 }
2884 2905
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2937 ASSERT(instr->HasPointerMap()); 2958 ASSERT(instr->HasPointerMap());
2938 ASSERT(instr->HasDeoptimizationEnvironment()); 2959 ASSERT(instr->HasDeoptimizationEnvironment());
2939 LPointerMap* pointers = instr->pointer_map(); 2960 LPointerMap* pointers = instr->pointer_map();
2940 LEnvironment* env = instr->deoptimization_environment(); 2961 LEnvironment* env = instr->deoptimization_environment();
2941 RecordPosition(pointers->position()); 2962 RecordPosition(pointers->position());
2942 RegisterEnvironmentForDeoptimization(env); 2963 RegisterEnvironmentForDeoptimization(env);
2943 SafepointGenerator generator(this, pointers, env->deoptimization_index()); 2964 SafepointGenerator generator(this, pointers, env->deoptimization_index());
2944 ParameterCount count(instr->arity()); 2965 ParameterCount count(instr->arity());
2945 __ InvokeFunction(rdi, count, CALL_FUNCTION, generator, CALL_AS_METHOD); 2966 __ InvokeFunction(rdi, count, CALL_FUNCTION, generator, CALL_AS_METHOD);
2946 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2967 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2968 __ movq(rsi, Immediate(0));
2947 } 2969 }
2948 2970
2949 2971
2950 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { 2972 void LCodeGen::DoCallKeyed(LCallKeyed* instr) {
2951 ASSERT(ToRegister(instr->key()).is(rcx)); 2973 ASSERT(ToRegister(instr->key()).is(rcx));
2952 ASSERT(ToRegister(instr->result()).is(rax)); 2974 ASSERT(ToRegister(instr->result()).is(rax));
2953 2975
2954 int arity = instr->arity(); 2976 int arity = instr->arity();
2955 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize( 2977 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(
2956 arity, NOT_IN_LOOP); 2978 arity, NOT_IN_LOOP);
2957 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2979 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2958 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2980 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2981 __ movq(rsi, Immediate(0));
2959 } 2982 }
2960 2983
2961 2984
2962 void LCodeGen::DoCallNamed(LCallNamed* instr) { 2985 void LCodeGen::DoCallNamed(LCallNamed* instr) {
2963 ASSERT(ToRegister(instr->result()).is(rax)); 2986 ASSERT(ToRegister(instr->result()).is(rax));
2964 2987
2965 int arity = instr->arity(); 2988 int arity = instr->arity();
2966 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; 2989 RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
2967 Handle<Code> ic = 2990 Handle<Code> ic =
2968 isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); 2991 isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode);
2969 __ Move(rcx, instr->name()); 2992 __ Move(rcx, instr->name());
2970 CallCode(ic, mode, instr); 2993 CallCode(ic, mode, instr);
2971 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2994 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2995 __ movq(rsi, Immediate(0));
2972 } 2996 }
2973 2997
2974 2998
2975 void LCodeGen::DoCallFunction(LCallFunction* instr) { 2999 void LCodeGen::DoCallFunction(LCallFunction* instr) {
2976 ASSERT(ToRegister(instr->result()).is(rax)); 3000 ASSERT(ToRegister(instr->result()).is(rax));
2977 3001
2978 int arity = instr->arity(); 3002 int arity = instr->arity();
2979 CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_IMPLICIT); 3003 CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_IMPLICIT);
2980 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 3004 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
2981 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 3005 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
3006 __ movq(rsi, Immediate(0));
2982 __ Drop(1); 3007 __ Drop(1);
2983 } 3008 }
2984 3009
2985 3010
2986 void LCodeGen::DoCallGlobal(LCallGlobal* instr) { 3011 void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
2987 ASSERT(ToRegister(instr->result()).is(rax)); 3012 ASSERT(ToRegister(instr->result()).is(rax));
2988 int arity = instr->arity(); 3013 int arity = instr->arity();
2989 RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT; 3014 RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT;
2990 Handle<Code> ic = 3015 Handle<Code> ic =
2991 isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); 3016 isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode);
2992 __ Move(rcx, instr->name()); 3017 __ Move(rcx, instr->name());
2993 CallCode(ic, mode, instr); 3018 CallCode(ic, mode, instr);
3019 __ movq(rsi, Immediate(0));
2994 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 3020 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
3021 __ movq(rsi, Immediate(0));
2995 } 3022 }
2996 3023
2997 3024
2998 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { 3025 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
2999 ASSERT(ToRegister(instr->result()).is(rax)); 3026 ASSERT(ToRegister(instr->result()).is(rax));
3000 __ Move(rdi, instr->target()); 3027 __ Move(rdi, instr->target());
3001 CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION); 3028 CallKnownFunction(instr->target(), instr->arity(), instr, CALL_AS_FUNCTION);
3002 } 3029 }
3003 3030
3004 3031
3005 void LCodeGen::DoCallNew(LCallNew* instr) { 3032 void LCodeGen::DoCallNew(LCallNew* instr) {
3006 ASSERT(ToRegister(instr->InputAt(0)).is(rdi)); 3033 ASSERT(ToRegister(instr->context()).is(rsi));
3034 ASSERT(ToRegister(instr->constructor()).is(rdi));
3007 ASSERT(ToRegister(instr->result()).is(rax)); 3035 ASSERT(ToRegister(instr->result()).is(rax));
3008 3036
3009 Handle<Code> builtin = isolate()->builtins()->JSConstructCall(); 3037 Handle<Code> builtin = isolate()->builtins()->JSConstructCall();
3010 __ Set(rax, instr->arity()); 3038 __ Set(rax, instr->arity());
3011 CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr); 3039 CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr);
3012 } 3040 }
3013 3041
3014 3042
3015 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { 3043 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
3016 CallRuntime(instr->function(), instr->arity(), instr); 3044 CallRuntime(instr->function(), instr->arity(), instr);
(...skipping 24 matching lines...) Expand all
3041 if (instr->needs_write_barrier()) { 3069 if (instr->needs_write_barrier()) {
3042 // Update the write barrier for the properties array. 3070 // Update the write barrier for the properties array.
3043 // object is used as a scratch register. 3071 // object is used as a scratch register.
3044 __ RecordWrite(temp, offset, value, object); 3072 __ RecordWrite(temp, offset, value, object);
3045 } 3073 }
3046 } 3074 }
3047 } 3075 }
3048 3076
3049 3077
3050 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { 3078 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
3079 ASSERT(ToRegister(instr->context()).is(rsi));
3051 ASSERT(ToRegister(instr->object()).is(rdx)); 3080 ASSERT(ToRegister(instr->object()).is(rdx));
3052 ASSERT(ToRegister(instr->value()).is(rax)); 3081 ASSERT(ToRegister(instr->value()).is(rax));
3053 3082
3054 __ Move(rcx, instr->hydrogen()->name()); 3083 __ Move(rcx, instr->hydrogen()->name());
3055 Handle<Code> ic = instr->strict_mode() 3084 Handle<Code> ic = instr->strict_mode()
3056 ? isolate()->builtins()->StoreIC_Initialize_Strict() 3085 ? isolate()->builtins()->StoreIC_Initialize_Strict()
3057 : isolate()->builtins()->StoreIC_Initialize(); 3086 : isolate()->builtins()->StoreIC_Initialize();
3058 CallCode(ic, RelocInfo::CODE_TARGET, instr); 3087 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3059 } 3088 }
3060 3089
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
3163 __ movq(value, kScratchRegister); 3192 __ movq(value, kScratchRegister);
3164 3193
3165 __ bind(&have_value); 3194 __ bind(&have_value);
3166 Operand double_store_operand = BuildFastArrayOperand( 3195 Operand double_store_operand = BuildFastArrayOperand(
3167 instr->elements(), instr->key(), JSObject::FAST_DOUBLE_ELEMENTS, 3196 instr->elements(), instr->key(), JSObject::FAST_DOUBLE_ELEMENTS,
3168 FixedDoubleArray::kHeaderSize - kHeapObjectTag); 3197 FixedDoubleArray::kHeaderSize - kHeapObjectTag);
3169 __ movsd(double_store_operand, value); 3198 __ movsd(double_store_operand, value);
3170 } 3199 }
3171 3200
3172 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 3201 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
3202 ASSERT(ToRegister(instr->context()).is(rsi));
3173 ASSERT(ToRegister(instr->object()).is(rdx)); 3203 ASSERT(ToRegister(instr->object()).is(rdx));
3174 ASSERT(ToRegister(instr->key()).is(rcx)); 3204 ASSERT(ToRegister(instr->key()).is(rcx));
3175 ASSERT(ToRegister(instr->value()).is(rax)); 3205 ASSERT(ToRegister(instr->value()).is(rax));
3176 3206
3177 Handle<Code> ic = instr->strict_mode() 3207 Handle<Code> ic = instr->strict_mode()
3178 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3208 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3179 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3209 : isolate()->builtins()->KeyedStoreIC_Initialize();
3180 CallCode(ic, RelocInfo::CODE_TARGET, instr); 3210 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3181 } 3211 }
3182 3212
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
3293 // DoStringCharCodeAt above. 3323 // DoStringCharCodeAt above.
3294 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue); 3324 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3295 if (instr->index()->IsConstantOperand()) { 3325 if (instr->index()->IsConstantOperand()) {
3296 int const_index = ToInteger32(LConstantOperand::cast(instr->index())); 3326 int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
3297 __ Push(Smi::FromInt(const_index)); 3327 __ Push(Smi::FromInt(const_index));
3298 } else { 3328 } else {
3299 Register index = ToRegister(instr->index()); 3329 Register index = ToRegister(instr->index());
3300 __ Integer32ToSmi(index, index); 3330 __ Integer32ToSmi(index, index);
3301 __ push(index); 3331 __ push(index);
3302 } 3332 }
3303 CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, instr); 3333 CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2,
3334 instr, instr->context());
3304 if (FLAG_debug_code) { 3335 if (FLAG_debug_code) {
3305 __ AbortIfNotSmi(rax); 3336 __ AbortIfNotSmi(rax);
3306 } 3337 }
3307 __ SmiToInteger32(rax, rax); 3338 __ SmiToInteger32(rax, rax);
3308 __ StoreToSafepointRegisterSlot(result, rax); 3339 __ StoreToSafepointRegisterSlot(result, rax);
3309 } 3340 }
3310 3341
3311 3342
3312 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { 3343 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
3313 class DeferredStringCharFromCode: public LDeferredCode { 3344 class DeferredStringCharFromCode: public LDeferredCode {
(...skipping 30 matching lines...) Expand all
3344 Register result = ToRegister(instr->result()); 3375 Register result = ToRegister(instr->result());
3345 3376
3346 // TODO(3095996): Get rid of this. For now, we need to make the 3377 // TODO(3095996): Get rid of this. For now, we need to make the
3347 // result register contain a valid pointer because it is already 3378 // result register contain a valid pointer because it is already
3348 // contained in the register pointer map. 3379 // contained in the register pointer map.
3349 __ Set(result, 0); 3380 __ Set(result, 0);
3350 3381
3351 PushSafepointRegistersScope scope(this); 3382 PushSafepointRegistersScope scope(this);
3352 __ Integer32ToSmi(char_code, char_code); 3383 __ Integer32ToSmi(char_code, char_code);
3353 __ push(char_code); 3384 __ push(char_code);
3354 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr); 3385 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context());
3355 __ StoreToSafepointRegisterSlot(result, rax); 3386 __ StoreToSafepointRegisterSlot(result, rax);
3356 } 3387 }
3357 3388
3358 3389
3359 void LCodeGen::DoStringLength(LStringLength* instr) { 3390 void LCodeGen::DoStringLength(LStringLength* instr) {
3360 Register string = ToRegister(instr->string()); 3391 Register string = ToRegister(instr->string());
3361 Register result = ToRegister(instr->result()); 3392 Register result = ToRegister(instr->result());
3362 __ movq(result, FieldOperand(string, String::kLengthOffset)); 3393 __ movq(result, FieldOperand(string, String::kLengthOffset));
3363 } 3394 }
3364 3395
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3412 3443
3413 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 3444 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
3414 // TODO(3095996): Get rid of this. For now, we need to make the 3445 // TODO(3095996): Get rid of this. For now, we need to make the
3415 // result register contain a valid pointer because it is already 3446 // result register contain a valid pointer because it is already
3416 // contained in the register pointer map. 3447 // contained in the register pointer map.
3417 Register reg = ToRegister(instr->result()); 3448 Register reg = ToRegister(instr->result());
3418 __ Move(reg, Smi::FromInt(0)); 3449 __ Move(reg, Smi::FromInt(0));
3419 3450
3420 { 3451 {
3421 PushSafepointRegistersScope scope(this); 3452 PushSafepointRegistersScope scope(this);
3422 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); 3453 // NumberTagD uses the context from the frame, rather than
3454 // the environment's HContext or HInlinedContext value.
3455 // It only calls Runtime::kAllocateHeapNumber.
3456 // The corresponding HChange instructions are added in a phase that does
3457 // not have easy access to the local context.
3458 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
3459 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
3460 RecordSafepointWithRegisters(instr->pointer_map(), 0,
3461 Safepoint::kNoDeoptimizationIndex);
3423 // Ensure that value in rax survives popping registers. 3462 // Ensure that value in rax survives popping registers.
3424 __ movq(kScratchRegister, rax); 3463 __ movq(kScratchRegister, rax);
3425 } 3464 }
3426 __ movq(reg, kScratchRegister); 3465 __ movq(reg, kScratchRegister);
3427 } 3466 }
3428 3467
3429 3468
3430 void LCodeGen::DoSmiTag(LSmiTag* instr) { 3469 void LCodeGen::DoSmiTag(LSmiTag* instr) {
3431 ASSERT(instr->InputAt(0)->Equals(instr->result())); 3470 ASSERT(instr->InputAt(0)->Equals(instr->result()));
3432 Register input = ToRegister(instr->InputAt(0)); 3471 Register input = ToRegister(instr->InputAt(0));
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
3877 __ movq(FieldOperand(rax, i + kPointerSize), rcx); 3916 __ movq(FieldOperand(rax, i + kPointerSize), rcx);
3878 } 3917 }
3879 if ((size % (2 * kPointerSize)) != 0) { 3918 if ((size % (2 * kPointerSize)) != 0) {
3880 __ movq(rdx, FieldOperand(rbx, size - kPointerSize)); 3919 __ movq(rdx, FieldOperand(rbx, size - kPointerSize));
3881 __ movq(FieldOperand(rax, size - kPointerSize), rdx); 3920 __ movq(FieldOperand(rax, size - kPointerSize), rdx);
3882 } 3921 }
3883 } 3922 }
3884 3923
3885 3924
3886 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { 3925 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
3926 ASSERT(ToRegister(instr->context()).is(rsi));
3887 // Use the fast case closure allocation code that allocates in new 3927 // Use the fast case closure allocation code that allocates in new
3888 // space for nested functions that don't need literals cloning. 3928 // space for nested functions that don't need literals cloning.
3889 Handle<SharedFunctionInfo> shared_info = instr->shared_info(); 3929 Handle<SharedFunctionInfo> shared_info = instr->shared_info();
3890 bool pretenure = instr->hydrogen()->pretenure(); 3930 bool pretenure = instr->hydrogen()->pretenure();
3891 if (!pretenure && shared_info->num_literals() == 0) { 3931 if (!pretenure && shared_info->num_literals() == 0) {
3892 FastNewClosureStub stub( 3932 FastNewClosureStub stub(
3893 shared_info->strict_mode() ? kStrictMode : kNonStrictMode); 3933 shared_info->strict_mode() ? kStrictMode : kNonStrictMode);
3894 __ Push(shared_info); 3934 __ Push(shared_info);
3895 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 3935 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
3896 } else { 3936 } else {
3897 __ push(rsi); 3937 __ push(rsi);
3898 __ Push(shared_info); 3938 __ Push(shared_info);
3899 __ PushRoot(pretenure ? 3939 __ PushRoot(pretenure ?
3900 Heap::kTrueValueRootIndex : 3940 Heap::kTrueValueRootIndex :
3901 Heap::kFalseValueRootIndex); 3941 Heap::kFalseValueRootIndex);
3902 CallRuntime(Runtime::kNewClosure, 3, instr); 3942 CallRuntime(Runtime::kNewClosure, 3, instr);
3903 } 3943 }
3904 } 3944 }
3905 3945
3906 3946
3907 void LCodeGen::DoTypeof(LTypeof* instr) { 3947 void LCodeGen::DoTypeof(LTypeof* instr) {
3908 LOperand* input = instr->InputAt(0); 3948 LOperand* input = instr->value();
3909 EmitPushTaggedOperand(input); 3949 EmitPushTaggedOperand(input);
3910 CallRuntime(Runtime::kTypeof, 1, instr); 3950 CallRuntime(Runtime::kTypeof, 1, instr);
3911 } 3951 }
3912 3952
3913 3953
3914 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) { 3954 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) {
3915 ASSERT(!operand->IsDoubleRegister()); 3955 ASSERT(!operand->IsDoubleRegister());
3916 if (operand->IsConstantOperand()) { 3956 if (operand->IsConstantOperand()) {
3917 __ Push(ToHandle(LConstantOperand::cast(operand))); 3957 __ Push(ToHandle(LConstantOperand::cast(operand)));
3918 } else if (operand->IsRegister()) { 3958 } else if (operand->IsRegister()) {
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
4083 // builtin) 4123 // builtin)
4084 SafepointGenerator safepoint_generator(this, 4124 SafepointGenerator safepoint_generator(this,
4085 pointers, 4125 pointers,
4086 env->deoptimization_index()); 4126 env->deoptimization_index());
4087 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); 4127 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator);
4088 } 4128 }
4089 4129
4090 4130
4091 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) { 4131 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
4092 { 4132 {
4133
4093 PushSafepointRegistersScope scope(this); 4134 PushSafepointRegistersScope scope(this);
4094 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 4135 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
4095 __ CallRuntimeSaveDoubles(Runtime::kStackGuard); 4136 __ CallRuntimeSaveDoubles(Runtime::kStackGuard);
4096 RegisterLazyDeoptimization(instr, RECORD_SAFEPOINT_WITH_REGISTERS, 0); 4137 RegisterLazyDeoptimization(instr, RECORD_SAFEPOINT_WITH_REGISTERS, 0);
4097 } 4138 }
4098 4139
4099 // The gap code includes the restoring of the safepoint registers. 4140 // The gap code includes the restoring of the safepoint registers.
4100 int pc = masm()->pc_offset(); 4141 int pc = masm()->pc_offset();
4101 safepoints_.SetPcAfterGap(pc); 4142 safepoints_.SetPcAfterGap(pc);
4102 } 4143 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
4147 RegisterEnvironmentForDeoptimization(environment); 4188 RegisterEnvironmentForDeoptimization(environment);
4148 ASSERT(osr_pc_offset_ == -1); 4189 ASSERT(osr_pc_offset_ == -1);
4149 osr_pc_offset_ = masm()->pc_offset(); 4190 osr_pc_offset_ = masm()->pc_offset();
4150 } 4191 }
4151 4192
4152 #undef __ 4193 #undef __
4153 4194
4154 } } // namespace v8::internal 4195 } } // namespace v8::internal
4155 4196
4156 #endif // V8_TARGET_ARCH_X64 4197 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698