OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
8 | 8 |
| 9 #include "src/code-factory.h" |
9 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 11 #include "src/codegen.h" |
11 #include "src/compiler.h" | 12 #include "src/compiler.h" |
12 #include "src/debug.h" | 13 #include "src/debug.h" |
13 #include "src/full-codegen.h" | 14 #include "src/full-codegen.h" |
14 #include "src/isolate-inl.h" | 15 #include "src/isolate-inl.h" |
15 #include "src/parser.h" | 16 #include "src/parser.h" |
16 #include "src/scopes.h" | 17 #include "src/scopes.h" |
17 | 18 |
18 #include "src/arm64/code-stubs-arm64.h" | 19 #include "src/arm64/code-stubs-arm64.h" |
(...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1043 patch_site.EmitJumpIfEitherNotSmi(x0, x1, &slow_case); | 1044 patch_site.EmitJumpIfEitherNotSmi(x0, x1, &slow_case); |
1044 __ Cmp(x1, x0); | 1045 __ Cmp(x1, x0); |
1045 __ B(ne, &next_test); | 1046 __ B(ne, &next_test); |
1046 __ Drop(1); // Switch value is no longer needed. | 1047 __ Drop(1); // Switch value is no longer needed. |
1047 __ B(clause->body_target()); | 1048 __ B(clause->body_target()); |
1048 __ Bind(&slow_case); | 1049 __ Bind(&slow_case); |
1049 } | 1050 } |
1050 | 1051 |
1051 // Record position before stub call for type feedback. | 1052 // Record position before stub call for type feedback. |
1052 SetSourcePosition(clause->position()); | 1053 SetSourcePosition(clause->position()); |
1053 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); | 1054 Handle<Code> ic = |
| 1055 CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code(); |
1054 CallIC(ic, clause->CompareId()); | 1056 CallIC(ic, clause->CompareId()); |
1055 patch_site.EmitPatchInfo(); | 1057 patch_site.EmitPatchInfo(); |
1056 | 1058 |
1057 Label skip; | 1059 Label skip; |
1058 __ B(&skip); | 1060 __ B(&skip); |
1059 PrepareForBailout(clause, TOS_REG); | 1061 PrepareForBailout(clause, TOS_REG); |
1060 __ JumpIfNotRoot(x0, Heap::kTrueValueRootIndex, &next_test); | 1062 __ JumpIfNotRoot(x0, Heap::kTrueValueRootIndex, &next_test); |
1061 __ Drop(1); | 1063 __ Drop(1); |
1062 __ B(clause->body_target()); | 1064 __ B(clause->body_target()); |
1063 __ Bind(&skip); | 1065 __ Bind(&skip); |
(...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1953 CallLoadIC(NOT_CONTEXTUAL); | 1955 CallLoadIC(NOT_CONTEXTUAL); |
1954 } else { | 1956 } else { |
1955 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); | 1957 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
1956 } | 1958 } |
1957 } | 1959 } |
1958 | 1960 |
1959 | 1961 |
1960 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1962 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
1961 SetSourcePosition(prop->position()); | 1963 SetSourcePosition(prop->position()); |
1962 // Call keyed load IC. It has arguments key and receiver in r0 and r1. | 1964 // Call keyed load IC. It has arguments key and receiver in r0 and r1. |
1963 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 1965 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); |
1964 if (FLAG_vector_ics) { | 1966 if (FLAG_vector_ics) { |
1965 __ Mov(VectorLoadICDescriptor::SlotRegister(), | 1967 __ Mov(VectorLoadICDescriptor::SlotRegister(), |
1966 Smi::FromInt(prop->PropertyFeedbackSlot())); | 1968 Smi::FromInt(prop->PropertyFeedbackSlot())); |
1967 CallIC(ic); | 1969 CallIC(ic); |
1968 } else { | 1970 } else { |
1969 CallIC(ic, prop->PropertyFeedbackId()); | 1971 CallIC(ic, prop->PropertyFeedbackId()); |
1970 } | 1972 } |
1971 } | 1973 } |
1972 | 1974 |
1973 | 1975 |
1974 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 1976 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
1975 Token::Value op, | 1977 Token::Value op, |
1976 OverwriteMode mode, | 1978 OverwriteMode mode, |
1977 Expression* left_expr, | 1979 Expression* left_expr, |
1978 Expression* right_expr) { | 1980 Expression* right_expr) { |
1979 Label done, both_smis, stub_call; | 1981 Label done, both_smis, stub_call; |
1980 | 1982 |
1981 // Get the arguments. | 1983 // Get the arguments. |
1982 Register left = x1; | 1984 Register left = x1; |
1983 Register right = x0; | 1985 Register right = x0; |
1984 Register result = x0; | 1986 Register result = x0; |
1985 __ Pop(left); | 1987 __ Pop(left); |
1986 | 1988 |
1987 // Perform combined smi check on both operands. | 1989 // Perform combined smi check on both operands. |
1988 __ Orr(x10, left, right); | 1990 __ Orr(x10, left, right); |
1989 JumpPatchSite patch_site(masm_); | 1991 JumpPatchSite patch_site(masm_); |
1990 patch_site.EmitJumpIfSmi(x10, &both_smis); | 1992 patch_site.EmitJumpIfSmi(x10, &both_smis); |
1991 | 1993 |
1992 __ Bind(&stub_call); | 1994 __ Bind(&stub_call); |
1993 BinaryOpICStub stub(isolate(), op, mode); | 1995 |
| 1996 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code(); |
1994 { | 1997 { |
1995 Assembler::BlockPoolsScope scope(masm_); | 1998 Assembler::BlockPoolsScope scope(masm_); |
1996 CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId()); | 1999 CallIC(code, expr->BinaryOperationFeedbackId()); |
1997 patch_site.EmitPatchInfo(); | 2000 patch_site.EmitPatchInfo(); |
1998 } | 2001 } |
1999 __ B(&done); | 2002 __ B(&done); |
2000 | 2003 |
2001 __ Bind(&both_smis); | 2004 __ Bind(&both_smis); |
2002 // Smi case. This code works in the same way as the smi-smi case in the type | 2005 // Smi case. This code works in the same way as the smi-smi case in the type |
2003 // recording binary operation stub, see | 2006 // recording binary operation stub, see |
2004 // BinaryOpStub::GenerateSmiSmiOperation for comments. | 2007 // BinaryOpStub::GenerateSmiSmiOperation for comments. |
2005 // TODO(all): That doesn't exist any more. Where are the comments? | 2008 // TODO(all): That doesn't exist any more. Where are the comments? |
2006 // | 2009 // |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2067 | 2070 |
2068 __ Bind(&done); | 2071 __ Bind(&done); |
2069 context()->Plug(x0); | 2072 context()->Plug(x0); |
2070 } | 2073 } |
2071 | 2074 |
2072 | 2075 |
2073 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 2076 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
2074 Token::Value op, | 2077 Token::Value op, |
2075 OverwriteMode mode) { | 2078 OverwriteMode mode) { |
2076 __ Pop(x1); | 2079 __ Pop(x1); |
2077 BinaryOpICStub stub(isolate(), op, mode); | 2080 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code(); |
2078 JumpPatchSite patch_site(masm_); // Unbound, signals no inlined smi code. | 2081 JumpPatchSite patch_site(masm_); // Unbound, signals no inlined smi code. |
2079 { | 2082 { |
2080 Assembler::BlockPoolsScope scope(masm_); | 2083 Assembler::BlockPoolsScope scope(masm_); |
2081 CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId()); | 2084 CallIC(code, expr->BinaryOperationFeedbackId()); |
2082 patch_site.EmitPatchInfo(); | 2085 patch_site.EmitPatchInfo(); |
2083 } | 2086 } |
2084 context()->Plug(x0); | 2087 context()->Plug(x0); |
2085 } | 2088 } |
2086 | 2089 |
2087 | 2090 |
2088 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2091 void FullCodeGenerator::EmitAssignment(Expression* expr) { |
2089 DCHECK(expr->IsValidReferenceExpression()); | 2092 DCHECK(expr->IsValidReferenceExpression()); |
2090 | 2093 |
2091 // Left-hand side can only be a property, a global or a (parameter or local) | 2094 // Left-hand side can only be a property, a global or a (parameter or local) |
(...skipping 26 matching lines...) Expand all Loading... |
2118 CallStoreIC(); | 2121 CallStoreIC(); |
2119 break; | 2122 break; |
2120 } | 2123 } |
2121 case KEYED_PROPERTY: { | 2124 case KEYED_PROPERTY: { |
2122 __ Push(x0); // Preserve value. | 2125 __ Push(x0); // Preserve value. |
2123 VisitForStackValue(prop->obj()); | 2126 VisitForStackValue(prop->obj()); |
2124 VisitForAccumulatorValue(prop->key()); | 2127 VisitForAccumulatorValue(prop->key()); |
2125 __ Mov(StoreDescriptor::NameRegister(), x0); | 2128 __ Mov(StoreDescriptor::NameRegister(), x0); |
2126 __ Pop(StoreDescriptor::ReceiverRegister(), | 2129 __ Pop(StoreDescriptor::ReceiverRegister(), |
2127 StoreDescriptor::ValueRegister()); | 2130 StoreDescriptor::ValueRegister()); |
2128 Handle<Code> ic = strict_mode() == SLOPPY | 2131 Handle<Code> ic = |
2129 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2132 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); |
2130 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | |
2131 CallIC(ic); | 2133 CallIC(ic); |
2132 break; | 2134 break; |
2133 } | 2135 } |
2134 } | 2136 } |
2135 context()->Plug(x0); | 2137 context()->Plug(x0); |
2136 } | 2138 } |
2137 | 2139 |
2138 | 2140 |
2139 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 2141 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
2140 Variable* var, MemOperand location) { | 2142 Variable* var, MemOperand location) { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2240 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2242 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2241 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment"); | 2243 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment"); |
2242 // Assignment to a property, using a keyed store IC. | 2244 // Assignment to a property, using a keyed store IC. |
2243 | 2245 |
2244 // Record source code position before IC call. | 2246 // Record source code position before IC call. |
2245 SetSourcePosition(expr->position()); | 2247 SetSourcePosition(expr->position()); |
2246 // TODO(all): Could we pass this in registers rather than on the stack? | 2248 // TODO(all): Could we pass this in registers rather than on the stack? |
2247 __ Pop(StoreDescriptor::NameRegister(), StoreDescriptor::ReceiverRegister()); | 2249 __ Pop(StoreDescriptor::NameRegister(), StoreDescriptor::ReceiverRegister()); |
2248 DCHECK(StoreDescriptor::ValueRegister().is(x0)); | 2250 DCHECK(StoreDescriptor::ValueRegister().is(x0)); |
2249 | 2251 |
2250 Handle<Code> ic = strict_mode() == SLOPPY | 2252 Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); |
2251 ? isolate()->builtins()->KeyedStoreIC_Initialize() | |
2252 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | |
2253 CallIC(ic, expr->AssignmentFeedbackId()); | 2253 CallIC(ic, expr->AssignmentFeedbackId()); |
2254 | 2254 |
2255 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2255 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2256 context()->Plug(x0); | 2256 context()->Plug(x0); |
2257 } | 2257 } |
2258 | 2258 |
2259 | 2259 |
2260 void FullCodeGenerator::VisitProperty(Property* expr) { | 2260 void FullCodeGenerator::VisitProperty(Property* expr) { |
2261 Comment cmnt(masm_, "[ Property"); | 2261 Comment cmnt(masm_, "[ Property"); |
2262 Expression* key = expr->key(); | 2262 Expression* key = expr->key(); |
(...skipping 1752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4015 | 4015 |
4016 __ Bind(&stub_call); | 4016 __ Bind(&stub_call); |
4017 __ Mov(x1, x0); | 4017 __ Mov(x1, x0); |
4018 __ Mov(x0, Smi::FromInt(count_value)); | 4018 __ Mov(x0, Smi::FromInt(count_value)); |
4019 | 4019 |
4020 // Record position before stub call. | 4020 // Record position before stub call. |
4021 SetSourcePosition(expr->position()); | 4021 SetSourcePosition(expr->position()); |
4022 | 4022 |
4023 { | 4023 { |
4024 Assembler::BlockPoolsScope scope(masm_); | 4024 Assembler::BlockPoolsScope scope(masm_); |
4025 BinaryOpICStub stub(isolate(), Token::ADD, NO_OVERWRITE); | 4025 Handle<Code> code = |
4026 CallIC(stub.GetCode(), expr->CountBinOpFeedbackId()); | 4026 CodeFactory::BinaryOpIC(isolate(), Token::ADD, NO_OVERWRITE).code(); |
| 4027 CallIC(code, expr->CountBinOpFeedbackId()); |
4027 patch_site.EmitPatchInfo(); | 4028 patch_site.EmitPatchInfo(); |
4028 } | 4029 } |
4029 __ Bind(&done); | 4030 __ Bind(&done); |
4030 | 4031 |
4031 // Store the value returned in x0. | 4032 // Store the value returned in x0. |
4032 switch (assign_type) { | 4033 switch (assign_type) { |
4033 case VARIABLE: | 4034 case VARIABLE: |
4034 if (expr->is_postfix()) { | 4035 if (expr->is_postfix()) { |
4035 { EffectContext context(this); | 4036 { EffectContext context(this); |
4036 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4037 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
(...skipping 24 matching lines...) Expand all Loading... |
4061 context()->PlugTOS(); | 4062 context()->PlugTOS(); |
4062 } | 4063 } |
4063 } else { | 4064 } else { |
4064 context()->Plug(x0); | 4065 context()->Plug(x0); |
4065 } | 4066 } |
4066 break; | 4067 break; |
4067 } | 4068 } |
4068 case KEYED_PROPERTY: { | 4069 case KEYED_PROPERTY: { |
4069 __ Pop(StoreDescriptor::NameRegister()); | 4070 __ Pop(StoreDescriptor::NameRegister()); |
4070 __ Pop(StoreDescriptor::ReceiverRegister()); | 4071 __ Pop(StoreDescriptor::ReceiverRegister()); |
4071 Handle<Code> ic = strict_mode() == SLOPPY | 4072 Handle<Code> ic = |
4072 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 4073 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); |
4073 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | |
4074 CallIC(ic, expr->CountStoreFeedbackId()); | 4074 CallIC(ic, expr->CountStoreFeedbackId()); |
4075 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4075 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4076 if (expr->is_postfix()) { | 4076 if (expr->is_postfix()) { |
4077 if (!context()->IsEffect()) { | 4077 if (!context()->IsEffect()) { |
4078 context()->PlugTOS(); | 4078 context()->PlugTOS(); |
4079 } | 4079 } |
4080 } else { | 4080 } else { |
4081 context()->Plug(x0); | 4081 context()->Plug(x0); |
4082 } | 4082 } |
4083 break; | 4083 break; |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4261 if (ShouldInlineSmiCase(op)) { | 4261 if (ShouldInlineSmiCase(op)) { |
4262 Label slow_case; | 4262 Label slow_case; |
4263 patch_site.EmitJumpIfEitherNotSmi(x0, x1, &slow_case); | 4263 patch_site.EmitJumpIfEitherNotSmi(x0, x1, &slow_case); |
4264 __ Cmp(x1, x0); | 4264 __ Cmp(x1, x0); |
4265 Split(cond, if_true, if_false, NULL); | 4265 Split(cond, if_true, if_false, NULL); |
4266 __ Bind(&slow_case); | 4266 __ Bind(&slow_case); |
4267 } | 4267 } |
4268 | 4268 |
4269 // Record position and call the compare IC. | 4269 // Record position and call the compare IC. |
4270 SetSourcePosition(expr->position()); | 4270 SetSourcePosition(expr->position()); |
4271 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); | 4271 Handle<Code> ic = CodeFactory::CompareIC(isolate(), op).code(); |
4272 CallIC(ic, expr->CompareOperationFeedbackId()); | 4272 CallIC(ic, expr->CompareOperationFeedbackId()); |
4273 patch_site.EmitPatchInfo(); | 4273 patch_site.EmitPatchInfo(); |
4274 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4274 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
4275 __ CompareAndSplit(x0, 0, cond, if_true, if_false, fall_through); | 4275 __ CompareAndSplit(x0, 0, cond, if_true, if_false, fall_through); |
4276 } | 4276 } |
4277 } | 4277 } |
4278 | 4278 |
4279 // Convert the result of the comparison into one expected for this | 4279 // Convert the result of the comparison into one expected for this |
4280 // expression's context. | 4280 // expression's context. |
4281 context()->Plug(if_true, if_false); | 4281 context()->Plug(if_true, if_false); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4447 __ Push(load_name, x3, x0); // "next", iter, received | 4447 __ Push(load_name, x3, x0); // "next", iter, received |
4448 | 4448 |
4449 // result = receiver[f](arg); | 4449 // result = receiver[f](arg); |
4450 __ Bind(&l_call); | 4450 __ Bind(&l_call); |
4451 __ Peek(load_receiver, 1 * kPointerSize); | 4451 __ Peek(load_receiver, 1 * kPointerSize); |
4452 __ Peek(load_name, 2 * kPointerSize); | 4452 __ Peek(load_name, 2 * kPointerSize); |
4453 if (FLAG_vector_ics) { | 4453 if (FLAG_vector_ics) { |
4454 __ Mov(VectorLoadICDescriptor::SlotRegister(), | 4454 __ Mov(VectorLoadICDescriptor::SlotRegister(), |
4455 Smi::FromInt(expr->KeyedLoadFeedbackSlot())); | 4455 Smi::FromInt(expr->KeyedLoadFeedbackSlot())); |
4456 } | 4456 } |
4457 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 4457 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); |
4458 CallIC(ic, TypeFeedbackId::None()); | 4458 CallIC(ic, TypeFeedbackId::None()); |
4459 __ Mov(x1, x0); | 4459 __ Mov(x1, x0); |
4460 __ Poke(x1, 2 * kPointerSize); | 4460 __ Poke(x1, 2 * kPointerSize); |
4461 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); | 4461 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); |
4462 __ CallStub(&stub); | 4462 __ CallStub(&stub); |
4463 | 4463 |
4464 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4464 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
4465 __ Drop(1); // The function is still on the stack; drop it. | 4465 __ Drop(1); // The function is still on the stack; drop it. |
4466 | 4466 |
4467 // if (!result.done) goto l_try; | 4467 // if (!result.done) goto l_try; |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4909 return previous_; | 4909 return previous_; |
4910 } | 4910 } |
4911 | 4911 |
4912 | 4912 |
4913 #undef __ | 4913 #undef __ |
4914 | 4914 |
4915 | 4915 |
4916 } } // namespace v8::internal | 4916 } } // namespace v8::internal |
4917 | 4917 |
4918 #endif // V8_TARGET_ARCH_ARM64 | 4918 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |