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

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

Issue 132623005: A64: Synchronize with r18642. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/a64/lithium-codegen-a64.h ('k') | src/a64/macro-assembler-a64.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 RelocInfo::Mode mode, 405 RelocInfo::Mode mode,
406 LInstruction* instr) { 406 LInstruction* instr) {
407 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT); 407 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT);
408 } 408 }
409 409
410 410
411 void LCodeGen::CallCodeGeneric(Handle<Code> code, 411 void LCodeGen::CallCodeGeneric(Handle<Code> code,
412 RelocInfo::Mode mode, 412 RelocInfo::Mode mode,
413 LInstruction* instr, 413 LInstruction* instr,
414 SafepointMode safepoint_mode) { 414 SafepointMode safepoint_mode) {
415 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
416 ASSERT(instr != NULL); 415 ASSERT(instr != NULL);
417 416
418 Assembler::BlockConstPoolScope scope(masm_); 417 Assembler::BlockConstPoolScope scope(masm_);
419 __ Call(code, mode); 418 __ Call(code, mode);
420 RecordSafepointWithLazyDeopt(instr, safepoint_mode); 419 RecordSafepointWithLazyDeopt(instr, safepoint_mode);
421 420
422 if ((code->kind() == Code::BINARY_OP_IC) || 421 if ((code->kind() == Code::BINARY_OP_IC) ||
423 (code->kind() == Code::COMPARE_IC)) { 422 (code->kind() == Code::COMPARE_IC)) {
424 // Signal that we don't inline smi code before these stubs in the 423 // Signal that we don't inline smi code before these stubs in the
425 // optimizing code generator. 424 // optimizing code generator.
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 658
660 // TODO(all): Add support for stop_t FLAG in DEBUG mode. 659 // TODO(all): Add support for stop_t FLAG in DEBUG mode.
661 660
662 // Classic mode functions and builtins need to replace the receiver with the 661 // Classic mode functions and builtins need to replace the receiver with the
663 // global proxy when called as functions (without an explicit receiver 662 // global proxy when called as functions (without an explicit receiver
664 // object). 663 // object).
665 if (info_->this_has_uses() && 664 if (info_->this_has_uses() &&
666 info_->is_classic_mode() && 665 info_->is_classic_mode() &&
667 !info_->is_native()) { 666 !info_->is_native()) {
668 Label ok; 667 Label ok;
669 __ Cbz(x5, &ok);
670 int receiver_offset = info_->scope()->num_parameters() * kXRegSizeInBytes; 668 int receiver_offset = info_->scope()->num_parameters() * kXRegSizeInBytes;
671 __ Peek(x10, receiver_offset); 669 __ Peek(x10, receiver_offset);
672 __ JumpIfNotRoot(x10, Heap::kUndefinedValueRootIndex, &ok); 670 __ JumpIfNotRoot(x10, Heap::kUndefinedValueRootIndex, &ok);
673 671
674 __ Ldr(x10, GlobalObjectMemOperand()); 672 __ Ldr(x10, GlobalObjectMemOperand());
675 __ Ldr(x10, FieldMemOperand(x10, GlobalObject::kGlobalReceiverOffset)); 673 __ Ldr(x10, FieldMemOperand(x10, GlobalObject::kGlobalReceiverOffset));
676 __ Poke(x10, receiver_offset); 674 __ Poke(x10, receiver_offset);
677 675
678 __ Bind(&ok); 676 __ Bind(&ok);
679 } 677 }
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
1056 Heap::RootListIndex index, 1054 Heap::RootListIndex index,
1057 LEnvironment* environment) { 1055 LEnvironment* environment) {
1058 Label dont_deopt; 1056 Label dont_deopt;
1059 __ JumpIfRoot(rt, index, &dont_deopt); 1057 __ JumpIfRoot(rt, index, &dont_deopt);
1060 Deoptimize(environment); 1058 Deoptimize(environment);
1061 __ Bind(&dont_deopt); 1059 __ Bind(&dont_deopt);
1062 } 1060 }
1063 1061
1064 1062
1065 void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) { 1063 void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) {
1066 if (info()->IsStub()) return; 1064 if (!info()->IsStub()) {
1067 // Ensure that we have enough space after the previous lazy-bailout 1065 // Ensure that we have enough space after the previous lazy-bailout
1068 // instruction for patching the code here. 1066 // instruction for patching the code here.
1069 intptr_t current_pc = masm()->pc_offset(); 1067 intptr_t current_pc = masm()->pc_offset();
1070 1068
1071 if (current_pc < (last_lazy_deopt_pc_ + space_needed)) { 1069 if (current_pc < (last_lazy_deopt_pc_ + space_needed)) {
1072 ptrdiff_t padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; 1070 ptrdiff_t padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
1073 ASSERT((padding_size % kInstructionSize) == 0); 1071 ASSERT((padding_size % kInstructionSize) == 0);
1074 InstructionAccurateScope instruction_accurate( 1072 InstructionAccurateScope instruction_accurate(
1075 masm(), padding_size / kInstructionSize); 1073 masm(), padding_size / kInstructionSize);
1076 1074
1077 while (padding_size > 0) { 1075 while (padding_size > 0) {
1078 __ nop(); 1076 __ nop();
1079 padding_size -= kInstructionSize; 1077 padding_size -= kInstructionSize;
1078 }
1080 } 1079 }
1081 } 1080 }
1081 last_lazy_deopt_pc_ = masm()->pc_offset();
1082 } 1082 }
1083 1083
1084 1084
1085 Register LCodeGen::ToRegister(LOperand* op) const { 1085 Register LCodeGen::ToRegister(LOperand* op) const {
1086 // TODO(all): support zero register results, as ToRegister32. 1086 // TODO(all): support zero register results, as ToRegister32.
1087 ASSERT((op != NULL) && op->IsRegister()); 1087 ASSERT((op != NULL) && op->IsRegister());
1088 return Register::FromAllocationIndex(op->index()); 1088 return Register::FromAllocationIndex(op->index());
1089 } 1089 }
1090 1090
1091 1091
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
1540 __ Subs(length, length, 1); 1540 __ Subs(length, length, 1);
1541 __ B(ne, &loop); 1541 __ B(ne, &loop);
1542 1542
1543 __ Bind(&invoke); 1543 __ Bind(&invoke);
1544 ASSERT(instr->HasPointerMap()); 1544 ASSERT(instr->HasPointerMap());
1545 LPointerMap* pointers = instr->pointer_map(); 1545 LPointerMap* pointers = instr->pointer_map();
1546 SafepointGenerator safepoint_generator(this, pointers, Safepoint::kLazyDeopt); 1546 SafepointGenerator safepoint_generator(this, pointers, Safepoint::kLazyDeopt);
1547 // The number of arguments is stored in argc (receiver) which is x0, as 1547 // The number of arguments is stored in argc (receiver) which is x0, as
1548 // expected by InvokeFunction. 1548 // expected by InvokeFunction.
1549 ParameterCount actual(argc); 1549 ParameterCount actual(argc);
1550 __ InvokeFunction(function, actual, CALL_FUNCTION, 1550 __ InvokeFunction(function, actual, CALL_FUNCTION, safepoint_generator);
1551 safepoint_generator, CALL_AS_FUNCTION);
1552 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1551 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1553 } 1552 }
1554 1553
1555 1554
1556 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { 1555 void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
1557 Register result = ToRegister(instr->result()); 1556 Register result = ToRegister(instr->result());
1558 1557
1559 if (instr->hydrogen()->from_inlined()) { 1558 if (instr->hydrogen()->from_inlined()) {
1560 // When we are inside an inlined function, the arguments are the last things 1559 // When we are inside an inlined function, the arguments are the last things
1561 // that have been pushed on the stack. Therefore the arguments array can be 1560 // that have been pushed on the stack. Therefore the arguments array can be
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
1849 } 1848 }
1850 } 1849 }
1851 } 1850 }
1852 } 1851 }
1853 1852
1854 1853
1855 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, 1854 void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
1856 int formal_parameter_count, 1855 int formal_parameter_count,
1857 int arity, 1856 int arity,
1858 LInstruction* instr, 1857 LInstruction* instr,
1859 CallKind call_kind,
1860 Register function_reg) { 1858 Register function_reg) {
1861 bool dont_adapt_arguments = 1859 bool dont_adapt_arguments =
1862 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; 1860 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel;
1863 bool can_invoke_directly = 1861 bool can_invoke_directly =
1864 dont_adapt_arguments || formal_parameter_count == arity; 1862 dont_adapt_arguments || formal_parameter_count == arity;
1865 1863
1866 // The function interface relies on the following register assignments. 1864 // The function interface relies on the following register assignments.
1867 ASSERT(function_reg.Is(x1) || function_reg.IsNone()); 1865 ASSERT(function_reg.Is(x1) || function_reg.IsNone());
1868 Register arity_reg = x0; 1866 Register arity_reg = x0;
1869 Register call_kind_reg = x5;
1870 1867
1871 LPointerMap* pointers = instr->pointer_map(); 1868 LPointerMap* pointers = instr->pointer_map();
1872 1869
1873 // If necessary, load the function object. 1870 // If necessary, load the function object.
1874 if (function_reg.IsNone()) { 1871 if (function_reg.IsNone()) {
1875 function_reg = x1; 1872 function_reg = x1;
1876 __ LoadObject(function_reg, function); 1873 __ LoadObject(function_reg, function);
1877 } 1874 }
1878 1875
1879 if (FLAG_debug_code) { 1876 if (FLAG_debug_code) {
1880 Label is_not_smi; 1877 Label is_not_smi;
1881 // Try to confirm that function_reg (x1) is a tagged pointer. 1878 // Try to confirm that function_reg (x1) is a tagged pointer.
1882 __ JumpIfNotSmi(function_reg, &is_not_smi); 1879 __ JumpIfNotSmi(function_reg, &is_not_smi);
1883 __ Abort(kExpectedFunctionObject); 1880 __ Abort(kExpectedFunctionObject);
1884 __ Bind(&is_not_smi); 1881 __ Bind(&is_not_smi);
1885 } 1882 }
1886 1883
1887 if (can_invoke_directly) { 1884 if (can_invoke_directly) {
1888 // Change context. 1885 // Change context.
1889 __ Ldr(cp, FieldMemOperand(function_reg, JSFunction::kContextOffset)); 1886 __ Ldr(cp, FieldMemOperand(function_reg, JSFunction::kContextOffset));
1890 1887
1891 // Set the arguments count if adaption is not needed. Assumes that x0 is 1888 // Set the arguments count if adaption is not needed. Assumes that x0 is
1892 // available to write to at this point. 1889 // available to write to at this point.
1893 if (dont_adapt_arguments) { 1890 if (dont_adapt_arguments) {
1894 __ Mov(arity_reg, arity); 1891 __ Mov(arity_reg, arity);
1895 } 1892 }
1896 1893
1897 // Invoke function. 1894 // Invoke function.
1898 __ SetCallKind(call_kind_reg, call_kind);
1899 __ Ldr(x10, FieldMemOperand(function_reg, JSFunction::kCodeEntryOffset)); 1895 __ Ldr(x10, FieldMemOperand(function_reg, JSFunction::kCodeEntryOffset));
1900 __ Call(x10); 1896 __ Call(x10);
1901 1897
1902 // Set up deoptimization. 1898 // Set up deoptimization.
1903 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 1899 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
1904 } else { 1900 } else {
1905 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 1901 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
1906 ParameterCount count(arity); 1902 ParameterCount count(arity);
1907 ParameterCount expected(formal_parameter_count); 1903 ParameterCount expected(formal_parameter_count);
1908 __ InvokeFunction( 1904 __ InvokeFunction(function_reg, expected, count, CALL_FUNCTION, generator);
1909 function_reg, expected, count, CALL_FUNCTION, generator, call_kind);
1910 } 1905 }
1911 1906
1912 // Restore context. 1907 // Restore context.
1913 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1908 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1914 } 1909 }
1915 1910
1916 1911
1917 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { 1912 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
1918 ASSERT(ToRegister(instr->result()).is(x0)); 1913 ASSERT(instr->IsMarkedAsCall());
1919 CallKnownFunction(instr->hydrogen()->function(), 1914 ASSERT(ToRegister(instr->result()).Is(x0));
1920 instr->hydrogen()->formal_parameter_count(), 1915
1921 instr->arity(), instr, CALL_AS_FUNCTION); 1916 LPointerMap* pointers = instr->pointer_map();
1917 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
1918
1919 if (instr->target()->IsConstantOperand()) {
1920 LConstantOperand* target = LConstantOperand::cast(instr->target());
1921 Handle<Code> code = Handle<Code>::cast(ToHandle(target));
1922 generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET));
1923 __ Call(code, RelocInfo::CODE_TARGET, TypeFeedbackId::None());
1924 } else {
1925 ASSERT(instr->target()->IsRegister());
1926 Register target = ToRegister(instr->target());
1927 generator.BeforeCall(__ CallSize(target));
1928 __ Add(target, target, Code::kHeaderSize - kHeapObjectTag);
1929 __ Call(target);
1930 }
1931 // TODO(jbramley): Is this load necessary?
1932 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1933 generator.AfterCall();
1922 } 1934 }
1923 1935
1924 1936
1925 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { 1937 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) {
1926 ASSERT(ToRegister(instr->result()).is(x0)); 1938 ASSERT(instr->IsMarkedAsCall());
1927 CallKnownFunction(instr->hydrogen()->target(), 1939 ASSERT(ToRegister(instr->function()).is(x1));
1928 instr->hydrogen()->formal_parameter_count(), 1940
1929 instr->arity(), instr, CALL_AS_FUNCTION); 1941 if (instr->hydrogen()->pass_argument_count()) {
1942 __ Mov(x0, Operand(instr->arity()));
1943 }
1944
1945 // Change context.
1946 __ Ldr(cp, FieldMemOperand(x1, JSFunction::kContextOffset));
1947
1948 // Load the code entry address
1949 __ Ldr(x10, FieldMemOperand(x1, JSFunction::kCodeEntryOffset));
1950 __ Call(x10);
1951
1952 // TODO(jbramley): Is this load necessary?
1953 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1954
1955 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
1930 } 1956 }
1931 1957
1932 1958
1933 void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
1934 ASSERT(ToRegister(instr->result()).is(x0));
1935
1936 int arity = instr->arity();
1937 Handle<Code> ic =
1938 isolate()->stub_cache()->ComputeCallInitialize(arity, CONTEXTUAL);
1939 __ Mov(x2, Operand(instr->name()));
1940 CallCode(ic, RelocInfo::CODE_TARGET, instr);
1941 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1942 }
1943
1944
1945 void LCodeGen::DoCallKeyed(LCallKeyed* instr) {
1946 ASSERT(ToRegister(instr->key()).Is(x2));
1947 ASSERT(ToRegister(instr->result()).Is(x0));
1948
1949 int arity = instr->arity();
1950 Handle<Code> ic =
1951 isolate()->stub_cache()->ComputeKeyedCallInitialize(arity);
1952 CallCode(ic, RelocInfo::CODE_TARGET, instr);
1953 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1954 }
1955
1956
1957 void LCodeGen::DoCallNamed(LCallNamed* instr) {
1958 ASSERT(ToRegister(instr->result()).is(x0));
1959
1960 int arity = instr->arity();
1961 Handle<Code> ic =
1962 isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_CONTEXTUAL);
1963
1964 // IC needs a pointer to the name of the function to be called in x2.
1965 __ Mov(x2, Operand(instr->name()));
1966 CallCode(ic, RelocInfo::CODE_TARGET, instr);
1967 // Restore context register.
1968 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1969 }
1970
1971
1972 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { 1959 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
1973 CallRuntime(instr->function(), instr->arity(), instr); 1960 CallRuntime(instr->function(), instr->arity(), instr);
1974 } 1961 }
1975 1962
1976 1963
1977 void LCodeGen::DoCallStub(LCallStub* instr) { 1964 void LCodeGen::DoCallStub(LCallStub* instr) {
1978 ASSERT(ToRegister(instr->result()).is(x0)); 1965 ASSERT(ToRegister(instr->result()).is(x0));
1979 switch (instr->hydrogen()->major_key()) { 1966 switch (instr->hydrogen()->major_key()) {
1980 case CodeStub::RegExpConstructResult: { 1967 case CodeStub::RegExpConstructResult: {
1981 RegExpConstructResultStub stub; 1968 RegExpConstructResultStub stub;
(...skipping 24 matching lines...) Expand all
2006 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { 1993 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
2007 GenerateOsrPrologue(); 1994 GenerateOsrPrologue();
2008 } 1995 }
2009 1996
2010 1997
2011 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { 1998 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
2012 Register temp = ToRegister(instr->temp()); 1999 Register temp = ToRegister(instr->temp());
2013 { 2000 {
2014 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 2001 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
2015 __ Push(object); 2002 __ Push(object);
2016 CallRuntimeFromDeferred(Runtime::kMigrateInstance, 1, instr); 2003 CallRuntimeFromDeferred(Runtime::kTryMigrateInstance, 1, instr);
2017 __ StoreToSafepointRegisterSlot(x0, temp); 2004 __ StoreToSafepointRegisterSlot(x0, temp);
2018 } 2005 }
2019 DeoptimizeIfSmi(temp, instr->environment()); 2006 DeoptimizeIfSmi(temp, instr->environment());
2020 } 2007 }
2021 2008
2022 2009
2023 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { 2010 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
2024 class DeferredCheckMaps: public LDeferredCode { 2011 class DeferredCheckMaps: public LDeferredCode {
2025 public: 2012 public:
2026 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object) 2013 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object)
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
2457 __ Cmp(reg, temp); 2444 __ Cmp(reg, temp);
2458 } else { 2445 } else {
2459 __ Cmp(reg, Operand(object)); 2446 __ Cmp(reg, Operand(object));
2460 } 2447 }
2461 DeoptimizeIf(ne, instr->environment()); 2448 DeoptimizeIf(ne, instr->environment());
2462 } 2449 }
2463 2450
2464 2451
2465 void LCodeGen::DoLazyBailout(LLazyBailout* instr) { 2452 void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
2466 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); 2453 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
2467 last_lazy_deopt_pc_ = masm()->pc_offset();
2468 ASSERT(instr->HasEnvironment()); 2454 ASSERT(instr->HasEnvironment());
2469 LEnvironment* env = instr->environment(); 2455 LEnvironment* env = instr->environment();
2470 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 2456 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
2471 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 2457 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
2472 } 2458 }
2473 2459
2474 2460
2475 void LCodeGen::DoDateField(LDateField* instr) { 2461 void LCodeGen::DoDateField(LDateField* instr) {
2476 Register object = ToRegister(instr->date()); 2462 Register object = ToRegister(instr->date());
2477 Register result = ToRegister(instr->result()); 2463 Register result = ToRegister(instr->result());
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after
3059 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { 3045 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
3060 // The function is required to be in x1. 3046 // The function is required to be in x1.
3061 ASSERT(ToRegister(instr->function()).is(x1)); 3047 ASSERT(ToRegister(instr->function()).is(x1));
3062 ASSERT(instr->HasPointerMap()); 3048 ASSERT(instr->HasPointerMap());
3063 3049
3064 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); 3050 Handle<JSFunction> known_function = instr->hydrogen()->known_function();
3065 if (known_function.is_null()) { 3051 if (known_function.is_null()) {
3066 LPointerMap* pointers = instr->pointer_map(); 3052 LPointerMap* pointers = instr->pointer_map();
3067 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 3053 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
3068 ParameterCount count(instr->arity()); 3054 ParameterCount count(instr->arity());
3069 __ InvokeFunction(x1, count, CALL_FUNCTION, generator, CALL_AS_FUNCTION); 3055 __ InvokeFunction(x1, count, CALL_FUNCTION, generator);
3070 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 3056 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
3071 } else { 3057 } else {
3072 CallKnownFunction(known_function, 3058 CallKnownFunction(known_function,
3073 instr->hydrogen()->formal_parameter_count(), 3059 instr->hydrogen()->formal_parameter_count(),
3074 instr->arity(), 3060 instr->arity(),
3075 instr, 3061 instr,
3076 CALL_AS_FUNCTION,
3077 x1); 3062 x1);
3078 } 3063 }
3079 } 3064 }
3080 3065
3081 3066
3082 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { 3067 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
3083 Register temp1 = ToRegister(instr->temp1()); 3068 Register temp1 = ToRegister(instr->temp1());
3084 Register temp2 = ToRegister(instr->temp2()); 3069 Register temp2 = ToRegister(instr->temp2());
3085 3070
3086 // Get the frame pointer for the calling frame. 3071 // Get the frame pointer for the calling frame.
(...skipping 1595 matching lines...) Expand 10 before | Expand all | Expand 10 after
4682 ASSERT(instr->HasEnvironment()); 4667 ASSERT(instr->HasEnvironment());
4683 LEnvironment* env = instr->environment(); 4668 LEnvironment* env = instr->environment();
4684 // There is no LLazyBailout instruction for stack-checks. We have to 4669 // There is no LLazyBailout instruction for stack-checks. We have to
4685 // prepare for lazy deoptimization explicitly here. 4670 // prepare for lazy deoptimization explicitly here.
4686 if (instr->hydrogen()->is_function_entry()) { 4671 if (instr->hydrogen()->is_function_entry()) {
4687 // Perform stack overflow check. 4672 // Perform stack overflow check.
4688 Label done; 4673 Label done;
4689 __ CompareRoot(masm()->StackPointer(), Heap::kStackLimitRootIndex); 4674 __ CompareRoot(masm()->StackPointer(), Heap::kStackLimitRootIndex);
4690 __ B(hs, &done); 4675 __ B(hs, &done);
4691 4676
4692 // TODO(bafsa): Make sure that the EnsureSpaceForLazyDeopt inside
4693 // CallCodeGeneric will not insert any nop while calling the stub by
4694 // inserting them now. The EnsureSpaceForLazyDeopt in CallCodeGeneric
4695 // will go away at some point during the rebase (r18642) so this will become
4696 // unecessary and should be removed at this point.
4697 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
4698
4699 PredictableCodeSizeScope predictable(masm_, 4677 PredictableCodeSizeScope predictable(masm_,
4700 Assembler::kCallSizeWithRelocation); 4678 Assembler::kCallSizeWithRelocation);
4701 CallCode(isolate()->builtins()->StackCheck(), 4679 CallCode(isolate()->builtins()->StackCheck(),
4702 RelocInfo::CODE_TARGET, 4680 RelocInfo::CODE_TARGET,
4703 instr); 4681 instr);
4704 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); 4682 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
4705 last_lazy_deopt_pc_ = masm()->pc_offset();
4706 4683
4707 __ Bind(&done); 4684 __ Bind(&done);
4708 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 4685 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
4709 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 4686 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
4710 } else { 4687 } else {
4711 ASSERT(instr->hydrogen()->is_backwards_branch()); 4688 ASSERT(instr->hydrogen()->is_backwards_branch());
4712 // Perform stack overflow check if this goto needs it before jumping. 4689 // Perform stack overflow check if this goto needs it before jumping.
4713 DeferredStackCheck* deferred_stack_check = 4690 DeferredStackCheck* deferred_stack_check =
4714 new(zone()) DeferredStackCheck(this, instr); 4691 new(zone()) DeferredStackCheck(this, instr);
4715 __ CompareRoot(masm()->StackPointer(), Heap::kStackLimitRootIndex); 4692 __ CompareRoot(masm()->StackPointer(), Heap::kStackLimitRootIndex);
4716 __ B(lo, deferred_stack_check->entry()); 4693 __ B(lo, deferred_stack_check->entry());
4717 4694
4718 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); 4695 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
4719 last_lazy_deopt_pc_ = masm()->pc_offset();
4720 __ Bind(instr->done_label()); 4696 __ Bind(instr->done_label());
4721 deferred_stack_check->SetExit(instr->done_label()); 4697 deferred_stack_check->SetExit(instr->done_label());
4722 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 4698 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
4723 // Don't record a deoptimization index for the safepoint here. 4699 // Don't record a deoptimization index for the safepoint here.
4724 // This will be done explicitly when emitting call and the safepoint in 4700 // This will be done explicitly when emitting call and the safepoint in
4725 // the deferred code. 4701 // the deferred code.
4726 } 4702 }
4727 } 4703 }
4728 4704
4729 4705
(...skipping 888 matching lines...) Expand 10 before | Expand all | Expand 10 after
5618 __ B(ge, &done); 5594 __ B(ge, &done);
5619 // Otherwise, fall through to deopt. 5595 // Otherwise, fall through to deopt.
5620 5596
5621 __ Bind(&deopt); 5597 __ Bind(&deopt);
5622 Deoptimize(instr->environment()); 5598 Deoptimize(instr->environment());
5623 5599
5624 __ Bind(&global_object); 5600 __ Bind(&global_object);
5625 // We could load directly into the result register here, but the additional 5601 // We could load directly into the result register here, but the additional
5626 // branches required are likely to be more time consuming than one additional 5602 // branches required are likely to be more time consuming than one additional
5627 // move. 5603 // move.
5628 // TODO(jbramley): This looks broken on ARM. There, a Context::SlotOffset() is
5629 // passed into ContextOperand.
5630 __ Ldr(receiver, FieldMemOperand(function, JSFunction::kContextOffset)); 5604 __ Ldr(receiver, FieldMemOperand(function, JSFunction::kContextOffset));
5631 __ Ldr(receiver, ContextMemOperand(receiver, Context::GLOBAL_OBJECT_INDEX)); 5605 __ Ldr(receiver, ContextMemOperand(receiver, Context::GLOBAL_OBJECT_INDEX));
5632 __ Ldr(receiver, 5606 __ Ldr(receiver,
5633 FieldMemOperand(receiver, GlobalObject::kGlobalReceiverOffset)); 5607 FieldMemOperand(receiver, GlobalObject::kGlobalReceiverOffset));
5634 5608
5635 __ Bind(&done); 5609 __ Bind(&done);
5636 __ Mov(result, receiver); 5610 __ Mov(result, receiver);
5637 } 5611 }
5638 5612
5639 5613
(...skipping 17 matching lines...) Expand all
5657 __ Bind(&out_of_object); 5631 __ Bind(&out_of_object);
5658 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); 5632 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
5659 // Index is equal to negated out of object property index plus 1. 5633 // Index is equal to negated out of object property index plus 1.
5660 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); 5634 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2));
5661 __ Ldr(result, FieldMemOperand(result, 5635 __ Ldr(result, FieldMemOperand(result,
5662 FixedArray::kHeaderSize - kPointerSize)); 5636 FixedArray::kHeaderSize - kPointerSize));
5663 __ Bind(&done); 5637 __ Bind(&done);
5664 } 5638 }
5665 5639
5666 } } // namespace v8::internal 5640 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/a64/lithium-codegen-a64.h ('k') | src/a64/macro-assembler-a64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698