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-factory.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 __ Pop(x0); | 491 __ Pop(x0); |
492 EmitProfilingCounterReset(); | 492 EmitProfilingCounterReset(); |
493 __ Bind(&ok); | 493 __ Bind(&ok); |
494 | 494 |
495 // Make sure that the constant pool is not emitted inside of the return | 495 // Make sure that the constant pool is not emitted inside of the return |
496 // sequence. This sequence can get patched when the debugger is used. See | 496 // sequence. This sequence can get patched when the debugger is used. See |
497 // debug-arm64.cc:BreakLocation::SetDebugBreakAtReturn(). | 497 // debug-arm64.cc:BreakLocation::SetDebugBreakAtReturn(). |
498 { | 498 { |
499 InstructionAccurateScope scope(masm_, | 499 InstructionAccurateScope scope(masm_, |
500 Assembler::kJSReturnSequenceInstructions); | 500 Assembler::kJSReturnSequenceInstructions); |
501 CodeGenerator::RecordPositions(masm_, function()->end_position() - 1); | 501 SetReturnPosition(function()); |
502 __ RecordJSReturn(); | 502 __ RecordJSReturn(); |
503 // This code is generated using Assembler methods rather than Macro | 503 // This code is generated using Assembler methods rather than Macro |
504 // Assembler methods because it will be patched later on, and so the size | 504 // Assembler methods because it will be patched later on, and so the size |
505 // of the generated code must be consistent. | 505 // of the generated code must be consistent. |
506 const Register& current_sp = __ StackPointer(); | 506 const Register& current_sp = __ StackPointer(); |
507 // Nothing ensures 16 bytes alignment here. | 507 // Nothing ensures 16 bytes alignment here. |
508 DCHECK(!current_sp.Is(csp)); | 508 DCHECK(!current_sp.Is(csp)); |
509 __ mov(current_sp, fp); | 509 __ mov(current_sp, fp); |
510 int no_frame_start = masm_->pc_offset(); | 510 int no_frame_start = masm_->pc_offset(); |
511 __ ldp(fp, lr, MemOperand(current_sp, 2 * kXRegSize, PostIndex)); | 511 __ ldp(fp, lr, MemOperand(current_sp, 2 * kXRegSize, PostIndex)); |
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1073 Label slow_case; | 1073 Label slow_case; |
1074 patch_site.EmitJumpIfEitherNotSmi(x0, x1, &slow_case); | 1074 patch_site.EmitJumpIfEitherNotSmi(x0, x1, &slow_case); |
1075 __ Cmp(x1, x0); | 1075 __ Cmp(x1, x0); |
1076 __ B(ne, &next_test); | 1076 __ B(ne, &next_test); |
1077 __ Drop(1); // Switch value is no longer needed. | 1077 __ Drop(1); // Switch value is no longer needed. |
1078 __ B(clause->body_target()); | 1078 __ B(clause->body_target()); |
1079 __ Bind(&slow_case); | 1079 __ Bind(&slow_case); |
1080 } | 1080 } |
1081 | 1081 |
1082 // Record position before stub call for type feedback. | 1082 // Record position before stub call for type feedback. |
1083 SetSourcePosition(clause->position()); | 1083 SetExpressionPosition(clause); |
1084 Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT, | 1084 Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT, |
1085 strength(language_mode())).code(); | 1085 strength(language_mode())).code(); |
1086 CallIC(ic, clause->CompareId()); | 1086 CallIC(ic, clause->CompareId()); |
1087 patch_site.EmitPatchInfo(); | 1087 patch_site.EmitPatchInfo(); |
1088 | 1088 |
1089 Label skip; | 1089 Label skip; |
1090 __ B(&skip); | 1090 __ B(&skip); |
1091 PrepareForBailout(clause, TOS_REG); | 1091 PrepareForBailout(clause, TOS_REG); |
1092 __ JumpIfNotRoot(x0, Heap::kTrueValueRootIndex, &next_test); | 1092 __ JumpIfNotRoot(x0, Heap::kTrueValueRootIndex, &next_test); |
1093 __ Drop(1); | 1093 __ Drop(1); |
(...skipping 25 matching lines...) Expand all Loading... |
1119 } | 1119 } |
1120 | 1120 |
1121 __ Bind(nested_statement.break_label()); | 1121 __ Bind(nested_statement.break_label()); |
1122 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 1122 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
1123 } | 1123 } |
1124 | 1124 |
1125 | 1125 |
1126 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { | 1126 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
1127 ASM_LOCATION("FullCodeGenerator::VisitForInStatement"); | 1127 ASM_LOCATION("FullCodeGenerator::VisitForInStatement"); |
1128 Comment cmnt(masm_, "[ ForInStatement"); | 1128 Comment cmnt(masm_, "[ ForInStatement"); |
| 1129 SetStatementPosition(stmt, SKIP_BREAK); |
| 1130 |
1129 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); | 1131 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); |
| 1132 |
1130 // TODO(all): This visitor probably needs better comments and a revisit. | 1133 // TODO(all): This visitor probably needs better comments and a revisit. |
1131 SetStatementPosition(stmt); | |
1132 | 1134 |
1133 Label loop, exit; | 1135 Label loop, exit; |
1134 ForIn loop_statement(this, stmt); | 1136 ForIn loop_statement(this, stmt); |
1135 increment_loop_depth(); | 1137 increment_loop_depth(); |
1136 | 1138 |
1137 // Get the object to enumerate over. If the object is null or undefined, skip | 1139 // Get the object to enumerate over. If the object is null or undefined, skip |
1138 // over the loop. See ECMA-262 version 5, section 12.6.4. | 1140 // over the loop. See ECMA-262 version 5, section 12.6.4. |
1139 SetExpressionPosition(stmt->enumerable()); | 1141 SetExpressionAsStatementPosition(stmt->enumerable()); |
1140 VisitForAccumulatorValue(stmt->enumerable()); | 1142 VisitForAccumulatorValue(stmt->enumerable()); |
1141 __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, &exit); | 1143 __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, &exit); |
1142 Register null_value = x15; | 1144 Register null_value = x15; |
1143 __ LoadRoot(null_value, Heap::kNullValueRootIndex); | 1145 __ LoadRoot(null_value, Heap::kNullValueRootIndex); |
1144 __ Cmp(x0, null_value); | 1146 __ Cmp(x0, null_value); |
1145 __ B(eq, &exit); | 1147 __ B(eq, &exit); |
1146 | 1148 |
1147 PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); | 1149 PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); |
1148 | 1150 |
1149 // Convert the object to a JS object. | 1151 // Convert the object to a JS object. |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1223 __ CompareObjectType(x10, x11, x12, LAST_JS_PROXY_TYPE); | 1225 __ CompareObjectType(x10, x11, x12, LAST_JS_PROXY_TYPE); |
1224 DCHECK(Smi::FromInt(0) == 0); | 1226 DCHECK(Smi::FromInt(0) == 0); |
1225 __ CzeroX(x1, le); // Zero indicates proxy. | 1227 __ CzeroX(x1, le); // Zero indicates proxy. |
1226 __ Ldr(x2, FieldMemOperand(x0, FixedArray::kLengthOffset)); | 1228 __ Ldr(x2, FieldMemOperand(x0, FixedArray::kLengthOffset)); |
1227 // Smi and array, fixed array length (as smi) and initial index. | 1229 // Smi and array, fixed array length (as smi) and initial index. |
1228 __ Push(x1, x0, x2, xzr); | 1230 __ Push(x1, x0, x2, xzr); |
1229 | 1231 |
1230 // Generate code for doing the condition check. | 1232 // Generate code for doing the condition check. |
1231 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); | 1233 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); |
1232 __ Bind(&loop); | 1234 __ Bind(&loop); |
1233 SetExpressionPosition(stmt->each()); | 1235 SetExpressionAsStatementPosition(stmt->each()); |
1234 | 1236 |
1235 // Load the current count to x0, load the length to x1. | 1237 // Load the current count to x0, load the length to x1. |
1236 __ PeekPair(x0, x1, 0); | 1238 __ PeekPair(x0, x1, 0); |
1237 __ Cmp(x0, x1); // Compare to the array length. | 1239 __ Cmp(x0, x1); // Compare to the array length. |
1238 __ B(hs, loop_statement.break_label()); | 1240 __ B(hs, loop_statement.break_label()); |
1239 | 1241 |
1240 // Get the current entry of the array into register r3. | 1242 // Get the current entry of the array into register r3. |
1241 __ Peek(x10, 2 * kXRegSize); | 1243 __ Peek(x10, 2 * kXRegSize); |
1242 __ Add(x10, x10, Operand::UntagSmiAndScale(x0, kPointerSizeLog2)); | 1244 __ Add(x10, x10, Operand::UntagSmiAndScale(x0, kPointerSizeLog2)); |
1243 __ Ldr(x3, MemOperand(x10, FixedArray::kHeaderSize - kHeapObjectTag)); | 1245 __ Ldr(x3, MemOperand(x10, FixedArray::kHeaderSize - kHeapObjectTag)); |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1462 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 1464 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
1463 } | 1465 } |
1464 } | 1466 } |
1465 __ B(done); | 1467 __ B(done); |
1466 } | 1468 } |
1467 } | 1469 } |
1468 | 1470 |
1469 | 1471 |
1470 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { | 1472 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
1471 // Record position before possible IC call. | 1473 // Record position before possible IC call. |
1472 SetSourcePosition(proxy->position()); | 1474 SetExpressionPosition(proxy); |
1473 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); | 1475 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); |
1474 Variable* var = proxy->var(); | 1476 Variable* var = proxy->var(); |
1475 | 1477 |
1476 // Three cases: global variables, lookup variables, and all other types of | 1478 // Three cases: global variables, lookup variables, and all other types of |
1477 // variables. | 1479 // variables. |
1478 switch (var->location()) { | 1480 switch (var->location()) { |
1479 case Variable::UNALLOCATED: { | 1481 case Variable::UNALLOCATED: { |
1480 Comment cmnt(masm_, "Global variable"); | 1482 Comment cmnt(masm_, "Global variable"); |
1481 __ Ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectMemOperand()); | 1483 __ Ldr(LoadDescriptor::ReceiverRegister(), GlobalObjectMemOperand()); |
1482 __ Mov(LoadDescriptor::NameRegister(), Operand(var->name())); | 1484 __ Mov(LoadDescriptor::NameRegister(), Operand(var->name())); |
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1952 } else { | 1954 } else { |
1953 context()->Plug(x0); | 1955 context()->Plug(x0); |
1954 } | 1956 } |
1955 } | 1957 } |
1956 | 1958 |
1957 | 1959 |
1958 void FullCodeGenerator::VisitAssignment(Assignment* expr) { | 1960 void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
1959 DCHECK(expr->target()->IsValidReferenceExpression()); | 1961 DCHECK(expr->target()->IsValidReferenceExpression()); |
1960 | 1962 |
1961 Comment cmnt(masm_, "[ Assignment"); | 1963 Comment cmnt(masm_, "[ Assignment"); |
| 1964 SetExpressionPosition(expr, INSERT_BREAK); |
1962 | 1965 |
1963 Property* property = expr->target()->AsProperty(); | 1966 Property* property = expr->target()->AsProperty(); |
1964 LhsKind assign_type = Property::GetAssignType(property); | 1967 LhsKind assign_type = Property::GetAssignType(property); |
1965 | 1968 |
1966 // Evaluate LHS expression. | 1969 // Evaluate LHS expression. |
1967 switch (assign_type) { | 1970 switch (assign_type) { |
1968 case VARIABLE: | 1971 case VARIABLE: |
1969 // Nothing to do here. | 1972 // Nothing to do here. |
1970 break; | 1973 break; |
1971 case NAMED_PROPERTY: | 1974 case NAMED_PROPERTY: |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2042 EmitKeyedPropertyLoad(property); | 2045 EmitKeyedPropertyLoad(property); |
2043 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 2046 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
2044 break; | 2047 break; |
2045 } | 2048 } |
2046 } | 2049 } |
2047 | 2050 |
2048 Token::Value op = expr->binary_op(); | 2051 Token::Value op = expr->binary_op(); |
2049 __ Push(x0); // Left operand goes on the stack. | 2052 __ Push(x0); // Left operand goes on the stack. |
2050 VisitForAccumulatorValue(expr->value()); | 2053 VisitForAccumulatorValue(expr->value()); |
2051 | 2054 |
2052 SetSourcePosition(expr->position() + 1); | |
2053 AccumulatorValueContext context(this); | 2055 AccumulatorValueContext context(this); |
2054 if (ShouldInlineSmiCase(op)) { | 2056 if (ShouldInlineSmiCase(op)) { |
2055 EmitInlineSmiBinaryOp(expr->binary_operation(), | 2057 EmitInlineSmiBinaryOp(expr->binary_operation(), |
2056 op, | 2058 op, |
2057 expr->target(), | 2059 expr->target(), |
2058 expr->value()); | 2060 expr->value()); |
2059 } else { | 2061 } else { |
2060 EmitBinaryOp(expr->binary_operation(), op); | 2062 EmitBinaryOp(expr->binary_operation(), op); |
2061 } | 2063 } |
2062 | 2064 |
2063 // Deoptimization point in case the binary operation may have side effects. | 2065 // Deoptimization point in case the binary operation may have side effects. |
2064 PrepareForBailout(expr->binary_operation(), TOS_REG); | 2066 PrepareForBailout(expr->binary_operation(), TOS_REG); |
2065 } else { | 2067 } else { |
2066 VisitForAccumulatorValue(expr->value()); | 2068 VisitForAccumulatorValue(expr->value()); |
2067 } | 2069 } |
2068 | 2070 |
2069 // Record source position before possible IC call. | 2071 SetExpressionPosition(expr); |
2070 SetSourcePosition(expr->position()); | |
2071 | 2072 |
2072 // Store the value. | 2073 // Store the value. |
2073 switch (assign_type) { | 2074 switch (assign_type) { |
2074 case VARIABLE: | 2075 case VARIABLE: |
2075 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 2076 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
2076 expr->op(), expr->AssignmentSlot()); | 2077 expr->op(), expr->AssignmentSlot()); |
2077 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2078 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2078 context()->Plug(x0); | 2079 context()->Plug(x0); |
2079 break; | 2080 break; |
2080 case NAMED_PROPERTY: | 2081 case NAMED_PROPERTY: |
2081 EmitNamedPropertyAssignment(expr); | 2082 EmitNamedPropertyAssignment(expr); |
2082 break; | 2083 break; |
2083 case NAMED_SUPER_PROPERTY: | 2084 case NAMED_SUPER_PROPERTY: |
2084 EmitNamedSuperPropertyStore(property); | 2085 EmitNamedSuperPropertyStore(property); |
2085 context()->Plug(x0); | 2086 context()->Plug(x0); |
2086 break; | 2087 break; |
2087 case KEYED_SUPER_PROPERTY: | 2088 case KEYED_SUPER_PROPERTY: |
2088 EmitKeyedSuperPropertyStore(property); | 2089 EmitKeyedSuperPropertyStore(property); |
2089 context()->Plug(x0); | 2090 context()->Plug(x0); |
2090 break; | 2091 break; |
2091 case KEYED_PROPERTY: | 2092 case KEYED_PROPERTY: |
2092 EmitKeyedPropertyAssignment(expr); | 2093 EmitKeyedPropertyAssignment(expr); |
2093 break; | 2094 break; |
2094 } | 2095 } |
2095 } | 2096 } |
2096 | 2097 |
2097 | 2098 |
2098 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2099 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
2099 SetSourcePosition(prop->position()); | 2100 SetExpressionPosition(prop); |
2100 Literal* key = prop->key()->AsLiteral(); | 2101 Literal* key = prop->key()->AsLiteral(); |
2101 DCHECK(!prop->IsSuperAccess()); | 2102 DCHECK(!prop->IsSuperAccess()); |
2102 | 2103 |
2103 __ Mov(LoadDescriptor::NameRegister(), Operand(key->value())); | 2104 __ Mov(LoadDescriptor::NameRegister(), Operand(key->value())); |
2104 __ Mov(LoadDescriptor::SlotRegister(), | 2105 __ Mov(LoadDescriptor::SlotRegister(), |
2105 SmiFromSlot(prop->PropertyFeedbackSlot())); | 2106 SmiFromSlot(prop->PropertyFeedbackSlot())); |
2106 CallLoadIC(NOT_CONTEXTUAL, language_mode()); | 2107 CallLoadIC(NOT_CONTEXTUAL, language_mode()); |
2107 } | 2108 } |
2108 | 2109 |
2109 | 2110 |
2110 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { | 2111 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { |
2111 // Stack: receiver, home_object. | 2112 // Stack: receiver, home_object. |
2112 SetSourcePosition(prop->position()); | 2113 SetExpressionPosition(prop); |
2113 Literal* key = prop->key()->AsLiteral(); | 2114 Literal* key = prop->key()->AsLiteral(); |
2114 DCHECK(!key->value()->IsSmi()); | 2115 DCHECK(!key->value()->IsSmi()); |
2115 DCHECK(prop->IsSuperAccess()); | 2116 DCHECK(prop->IsSuperAccess()); |
2116 | 2117 |
2117 __ Push(key->value()); | 2118 __ Push(key->value()); |
2118 __ Push(Smi::FromInt(language_mode())); | 2119 __ Push(Smi::FromInt(language_mode())); |
2119 __ CallRuntime(Runtime::kLoadFromSuper, 4); | 2120 __ CallRuntime(Runtime::kLoadFromSuper, 4); |
2120 } | 2121 } |
2121 | 2122 |
2122 | 2123 |
2123 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2124 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
2124 SetSourcePosition(prop->position()); | 2125 SetExpressionPosition(prop); |
2125 // Call keyed load IC. It has arguments key and receiver in x0 and x1. | 2126 // Call keyed load IC. It has arguments key and receiver in x0 and x1. |
2126 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code(); | 2127 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code(); |
2127 __ Mov(LoadDescriptor::SlotRegister(), | 2128 __ Mov(LoadDescriptor::SlotRegister(), |
2128 SmiFromSlot(prop->PropertyFeedbackSlot())); | 2129 SmiFromSlot(prop->PropertyFeedbackSlot())); |
2129 CallIC(ic); | 2130 CallIC(ic); |
2130 } | 2131 } |
2131 | 2132 |
2132 | 2133 |
2133 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { | 2134 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { |
2134 // Stack: receiver, home_object, key. | 2135 // Stack: receiver, home_object, key. |
| 2136 SetExpressionPosition(prop); |
2135 __ Push(Smi::FromInt(language_mode())); | 2137 __ Push(Smi::FromInt(language_mode())); |
2136 SetSourcePosition(prop->position()); | |
2137 | |
2138 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); | 2138 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); |
2139 } | 2139 } |
2140 | 2140 |
2141 | 2141 |
2142 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2142 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
2143 Token::Value op, | 2143 Token::Value op, |
2144 Expression* left_expr, | 2144 Expression* left_expr, |
2145 Expression* right_expr) { | 2145 Expression* right_expr) { |
2146 Label done, both_smis, stub_call; | 2146 Label done, both_smis, stub_call; |
2147 | 2147 |
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2511 } | 2511 } |
2512 | 2512 |
2513 | 2513 |
2514 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2514 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
2515 ASM_LOCATION("FullCodeGenerator::EmitNamedPropertyAssignment"); | 2515 ASM_LOCATION("FullCodeGenerator::EmitNamedPropertyAssignment"); |
2516 // Assignment to a property, using a named store IC. | 2516 // Assignment to a property, using a named store IC. |
2517 Property* prop = expr->target()->AsProperty(); | 2517 Property* prop = expr->target()->AsProperty(); |
2518 DCHECK(prop != NULL); | 2518 DCHECK(prop != NULL); |
2519 DCHECK(prop->key()->IsLiteral()); | 2519 DCHECK(prop->key()->IsLiteral()); |
2520 | 2520 |
2521 // Record source code position before IC call. | |
2522 SetSourcePosition(expr->position()); | |
2523 __ Mov(StoreDescriptor::NameRegister(), | 2521 __ Mov(StoreDescriptor::NameRegister(), |
2524 Operand(prop->key()->AsLiteral()->value())); | 2522 Operand(prop->key()->AsLiteral()->value())); |
2525 __ Pop(StoreDescriptor::ReceiverRegister()); | 2523 __ Pop(StoreDescriptor::ReceiverRegister()); |
2526 if (FLAG_vector_stores) { | 2524 if (FLAG_vector_stores) { |
2527 EmitLoadStoreICSlot(expr->AssignmentSlot()); | 2525 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
2528 CallStoreIC(); | 2526 CallStoreIC(); |
2529 } else { | 2527 } else { |
2530 CallStoreIC(expr->AssignmentFeedbackId()); | 2528 CallStoreIC(expr->AssignmentFeedbackId()); |
2531 } | 2529 } |
2532 | 2530 |
(...skipping 29 matching lines...) Expand all Loading... |
2562 (is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict | 2560 (is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
2563 : Runtime::kStoreKeyedToSuper_Sloppy), | 2561 : Runtime::kStoreKeyedToSuper_Sloppy), |
2564 4); | 2562 4); |
2565 } | 2563 } |
2566 | 2564 |
2567 | 2565 |
2568 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2566 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2569 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment"); | 2567 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment"); |
2570 // Assignment to a property, using a keyed store IC. | 2568 // Assignment to a property, using a keyed store IC. |
2571 | 2569 |
2572 // Record source code position before IC call. | |
2573 SetSourcePosition(expr->position()); | |
2574 // TODO(all): Could we pass this in registers rather than on the stack? | 2570 // TODO(all): Could we pass this in registers rather than on the stack? |
2575 __ Pop(StoreDescriptor::NameRegister(), StoreDescriptor::ReceiverRegister()); | 2571 __ Pop(StoreDescriptor::NameRegister(), StoreDescriptor::ReceiverRegister()); |
2576 DCHECK(StoreDescriptor::ValueRegister().is(x0)); | 2572 DCHECK(StoreDescriptor::ValueRegister().is(x0)); |
2577 | 2573 |
2578 Handle<Code> ic = | 2574 Handle<Code> ic = |
2579 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2575 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
2580 if (FLAG_vector_stores) { | 2576 if (FLAG_vector_stores) { |
2581 EmitLoadStoreICSlot(expr->AssignmentSlot()); | 2577 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
2582 CallIC(ic); | 2578 CallIC(ic); |
2583 } else { | 2579 } else { |
2584 CallIC(ic, expr->AssignmentFeedbackId()); | 2580 CallIC(ic, expr->AssignmentFeedbackId()); |
2585 } | 2581 } |
2586 | 2582 |
2587 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2583 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2588 context()->Plug(x0); | 2584 context()->Plug(x0); |
2589 } | 2585 } |
2590 | 2586 |
2591 | 2587 |
2592 void FullCodeGenerator::VisitProperty(Property* expr) { | 2588 void FullCodeGenerator::VisitProperty(Property* expr) { |
2593 Comment cmnt(masm_, "[ Property"); | 2589 Comment cmnt(masm_, "[ Property"); |
| 2590 SetExpressionPosition(expr); |
2594 Expression* key = expr->key(); | 2591 Expression* key = expr->key(); |
2595 | 2592 |
2596 if (key->IsPropertyName()) { | 2593 if (key->IsPropertyName()) { |
2597 if (!expr->IsSuperAccess()) { | 2594 if (!expr->IsSuperAccess()) { |
2598 VisitForAccumulatorValue(expr->obj()); | 2595 VisitForAccumulatorValue(expr->obj()); |
2599 __ Move(LoadDescriptor::ReceiverRegister(), x0); | 2596 __ Move(LoadDescriptor::ReceiverRegister(), x0); |
2600 EmitNamedPropertyLoad(expr); | 2597 EmitNamedPropertyLoad(expr); |
2601 } else { | 2598 } else { |
2602 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); | 2599 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); |
2603 VisitForStackValue( | 2600 VisitForStackValue( |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2668 | 2665 |
2669 EmitCall(expr, call_type); | 2666 EmitCall(expr, call_type); |
2670 } | 2667 } |
2671 | 2668 |
2672 | 2669 |
2673 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | 2670 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { |
2674 Expression* callee = expr->expression(); | 2671 Expression* callee = expr->expression(); |
2675 DCHECK(callee->IsProperty()); | 2672 DCHECK(callee->IsProperty()); |
2676 Property* prop = callee->AsProperty(); | 2673 Property* prop = callee->AsProperty(); |
2677 DCHECK(prop->IsSuperAccess()); | 2674 DCHECK(prop->IsSuperAccess()); |
| 2675 SetExpressionPosition(prop); |
2678 | 2676 |
2679 SetSourcePosition(prop->position()); | |
2680 Literal* key = prop->key()->AsLiteral(); | 2677 Literal* key = prop->key()->AsLiteral(); |
2681 DCHECK(!key->value()->IsSmi()); | 2678 DCHECK(!key->value()->IsSmi()); |
2682 | 2679 |
2683 // Load the function from the receiver. | 2680 // Load the function from the receiver. |
2684 const Register scratch = x10; | 2681 const Register scratch = x10; |
2685 SuperPropertyReference* super_ref = | 2682 SuperPropertyReference* super_ref = |
2686 callee->AsProperty()->obj()->AsSuperPropertyReference(); | 2683 callee->AsProperty()->obj()->AsSuperPropertyReference(); |
2687 VisitForStackValue(super_ref->home_object()); | 2684 VisitForStackValue(super_ref->home_object()); |
2688 VisitForAccumulatorValue(super_ref->this_var()); | 2685 VisitForAccumulatorValue(super_ref->this_var()); |
2689 __ Push(x0); | 2686 __ Push(x0); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2731 | 2728 |
2732 EmitCall(expr, CallICState::METHOD); | 2729 EmitCall(expr, CallICState::METHOD); |
2733 } | 2730 } |
2734 | 2731 |
2735 | 2732 |
2736 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | 2733 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { |
2737 Expression* callee = expr->expression(); | 2734 Expression* callee = expr->expression(); |
2738 DCHECK(callee->IsProperty()); | 2735 DCHECK(callee->IsProperty()); |
2739 Property* prop = callee->AsProperty(); | 2736 Property* prop = callee->AsProperty(); |
2740 DCHECK(prop->IsSuperAccess()); | 2737 DCHECK(prop->IsSuperAccess()); |
2741 | 2738 SetExpressionPosition(prop); |
2742 SetSourcePosition(prop->position()); | |
2743 | 2739 |
2744 // Load the function from the receiver. | 2740 // Load the function from the receiver. |
2745 const Register scratch = x10; | 2741 const Register scratch = x10; |
2746 SuperPropertyReference* super_ref = | 2742 SuperPropertyReference* super_ref = |
2747 callee->AsProperty()->obj()->AsSuperPropertyReference(); | 2743 callee->AsProperty()->obj()->AsSuperPropertyReference(); |
2748 VisitForStackValue(super_ref->home_object()); | 2744 VisitForStackValue(super_ref->home_object()); |
2749 VisitForAccumulatorValue(super_ref->this_var()); | 2745 VisitForAccumulatorValue(super_ref->this_var()); |
2750 __ Push(x0); | 2746 __ Push(x0); |
2751 __ Peek(scratch, kPointerSize); | 2747 __ Peek(scratch, kPointerSize); |
2752 __ Push(x0, scratch); | 2748 __ Push(x0, scratch); |
(...skipping 16 matching lines...) Expand all Loading... |
2769 // - target function | 2765 // - target function |
2770 // - this (receiver) | 2766 // - this (receiver) |
2771 EmitCall(expr, CallICState::METHOD); | 2767 EmitCall(expr, CallICState::METHOD); |
2772 } | 2768 } |
2773 | 2769 |
2774 | 2770 |
2775 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) { | 2771 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) { |
2776 // Load the arguments. | 2772 // Load the arguments. |
2777 ZoneList<Expression*>* args = expr->arguments(); | 2773 ZoneList<Expression*>* args = expr->arguments(); |
2778 int arg_count = args->length(); | 2774 int arg_count = args->length(); |
2779 { PreservePositionScope scope(masm()->positions_recorder()); | |
2780 for (int i = 0; i < arg_count; i++) { | 2775 for (int i = 0; i < arg_count; i++) { |
2781 VisitForStackValue(args->at(i)); | 2776 VisitForStackValue(args->at(i)); |
2782 } | 2777 } |
2783 } | 2778 SetExpressionPosition(expr); |
2784 // Record source position of the IC call. | |
2785 SetSourcePosition(expr->position()); | |
2786 | 2779 |
2787 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code(); | 2780 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code(); |
2788 __ Mov(x3, SmiFromSlot(expr->CallFeedbackICSlot())); | 2781 __ Mov(x3, SmiFromSlot(expr->CallFeedbackICSlot())); |
2789 __ Peek(x1, (arg_count + 1) * kXRegSize); | 2782 __ Peek(x1, (arg_count + 1) * kXRegSize); |
2790 // Don't assign a type feedback id to the IC, since type feedback is provided | 2783 // Don't assign a type feedback id to the IC, since type feedback is provided |
2791 // by the vector above. | 2784 // by the vector above. |
2792 CallIC(ic); | 2785 CallIC(ic); |
2793 | 2786 |
2794 RecordJSReturnSite(expr); | 2787 RecordJSReturnSite(expr); |
2795 // Restore context register. | 2788 // Restore context register. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2836 | 2829 |
2837 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); | 2830 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); |
2838 } | 2831 } |
2839 | 2832 |
2840 | 2833 |
2841 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. | 2834 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. |
2842 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { | 2835 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { |
2843 VariableProxy* callee = expr->expression()->AsVariableProxy(); | 2836 VariableProxy* callee = expr->expression()->AsVariableProxy(); |
2844 if (callee->var()->IsLookupSlot()) { | 2837 if (callee->var()->IsLookupSlot()) { |
2845 Label slow, done; | 2838 Label slow, done; |
2846 SetSourcePosition(callee->position()); | 2839 SetExpressionPosition(callee); |
2847 { | |
2848 PreservePositionScope scope(masm()->positions_recorder()); | |
2849 // Generate code for loading from variables potentially shadowed | 2840 // Generate code for loading from variables potentially shadowed |
2850 // by eval-introduced variables. | 2841 // by eval-introduced variables. |
2851 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); | 2842 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); |
2852 } | |
2853 | 2843 |
2854 __ Bind(&slow); | 2844 __ Bind(&slow); |
2855 // Call the runtime to find the function to call (returned in x0) | 2845 // Call the runtime to find the function to call (returned in x0) |
2856 // and the object holding it (returned in x1). | 2846 // and the object holding it (returned in x1). |
2857 __ Mov(x10, Operand(callee->name())); | 2847 __ Mov(x10, Operand(callee->name())); |
2858 __ Push(context_register(), x10); | 2848 __ Push(context_register(), x10); |
2859 __ CallRuntime(Runtime::kLoadLookupSlot, 2); | 2849 __ CallRuntime(Runtime::kLoadLookupSlot, 2); |
2860 __ Push(x0, x1); // Receiver, function. | 2850 __ Push(x0, x1); // Receiver, function. |
2861 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); | 2851 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); |
2862 | 2852 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2894 Expression* callee = expr->expression(); | 2884 Expression* callee = expr->expression(); |
2895 Call::CallType call_type = expr->GetCallType(isolate()); | 2885 Call::CallType call_type = expr->GetCallType(isolate()); |
2896 | 2886 |
2897 if (call_type == Call::POSSIBLY_EVAL_CALL) { | 2887 if (call_type == Call::POSSIBLY_EVAL_CALL) { |
2898 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval | 2888 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval |
2899 // to resolve the function we need to call. Then we call the resolved | 2889 // to resolve the function we need to call. Then we call the resolved |
2900 // function using the given arguments. | 2890 // function using the given arguments. |
2901 ZoneList<Expression*>* args = expr->arguments(); | 2891 ZoneList<Expression*>* args = expr->arguments(); |
2902 int arg_count = args->length(); | 2892 int arg_count = args->length(); |
2903 | 2893 |
2904 { | |
2905 PreservePositionScope pos_scope(masm()->positions_recorder()); | |
2906 PushCalleeAndWithBaseObject(expr); | 2894 PushCalleeAndWithBaseObject(expr); |
2907 | 2895 |
2908 // Push the arguments. | 2896 // Push the arguments. |
2909 for (int i = 0; i < arg_count; i++) { | 2897 for (int i = 0; i < arg_count; i++) { |
2910 VisitForStackValue(args->at(i)); | 2898 VisitForStackValue(args->at(i)); |
2911 } | 2899 } |
2912 | 2900 |
2913 // Push a copy of the function (found below the arguments) and | 2901 // Push a copy of the function (found below the arguments) and |
2914 // resolve eval. | 2902 // resolve eval. |
2915 __ Peek(x10, (arg_count + 1) * kPointerSize); | 2903 __ Peek(x10, (arg_count + 1) * kPointerSize); |
2916 __ Push(x10); | 2904 __ Push(x10); |
2917 EmitResolvePossiblyDirectEval(arg_count); | 2905 EmitResolvePossiblyDirectEval(arg_count); |
2918 | 2906 |
2919 // Touch up the stack with the resolved function. | 2907 // Touch up the stack with the resolved function. |
2920 __ Poke(x0, (arg_count + 1) * kPointerSize); | 2908 __ Poke(x0, (arg_count + 1) * kPointerSize); |
2921 | 2909 |
2922 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); | 2910 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); |
2923 } | |
2924 | 2911 |
2925 // Record source position for debugger. | 2912 // Record source position for debugger. |
2926 SetSourcePosition(expr->position()); | 2913 SetExpressionPosition(expr); |
2927 | 2914 |
2928 // Call the evaluated function. | 2915 // Call the evaluated function. |
2929 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | 2916 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
2930 __ Peek(x1, (arg_count + 1) * kXRegSize); | 2917 __ Peek(x1, (arg_count + 1) * kXRegSize); |
2931 __ CallStub(&stub); | 2918 __ CallStub(&stub); |
2932 RecordJSReturnSite(expr); | 2919 RecordJSReturnSite(expr); |
2933 // Restore context register. | 2920 // Restore context register. |
2934 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2921 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2935 context()->DropAndPlug(1, x0); | 2922 context()->DropAndPlug(1, x0); |
2936 | 2923 |
2937 } else if (call_type == Call::GLOBAL_CALL) { | 2924 } else if (call_type == Call::GLOBAL_CALL) { |
2938 EmitCallWithLoadIC(expr); | 2925 EmitCallWithLoadIC(expr); |
2939 | 2926 |
2940 } else if (call_type == Call::LOOKUP_SLOT_CALL) { | 2927 } else if (call_type == Call::LOOKUP_SLOT_CALL) { |
2941 // Call to a lookup slot (dynamically introduced variable). | 2928 // Call to a lookup slot (dynamically introduced variable). |
2942 PushCalleeAndWithBaseObject(expr); | 2929 PushCalleeAndWithBaseObject(expr); |
2943 EmitCall(expr); | 2930 EmitCall(expr); |
2944 } else if (call_type == Call::PROPERTY_CALL) { | 2931 } else if (call_type == Call::PROPERTY_CALL) { |
2945 Property* property = callee->AsProperty(); | 2932 Property* property = callee->AsProperty(); |
2946 bool is_named_call = property->key()->IsPropertyName(); | 2933 bool is_named_call = property->key()->IsPropertyName(); |
2947 if (property->IsSuperAccess()) { | 2934 if (property->IsSuperAccess()) { |
2948 if (is_named_call) { | 2935 if (is_named_call) { |
2949 EmitSuperCallWithLoadIC(expr); | 2936 EmitSuperCallWithLoadIC(expr); |
2950 } else { | 2937 } else { |
2951 EmitKeyedSuperCallWithLoadIC(expr); | 2938 EmitKeyedSuperCallWithLoadIC(expr); |
2952 } | 2939 } |
2953 } else { | 2940 } else { |
2954 { | |
2955 PreservePositionScope scope(masm()->positions_recorder()); | |
2956 VisitForStackValue(property->obj()); | 2941 VisitForStackValue(property->obj()); |
2957 } | |
2958 if (is_named_call) { | 2942 if (is_named_call) { |
2959 EmitCallWithLoadIC(expr); | 2943 EmitCallWithLoadIC(expr); |
2960 } else { | 2944 } else { |
2961 EmitKeyedCallWithLoadIC(expr, property->key()); | 2945 EmitKeyedCallWithLoadIC(expr, property->key()); |
2962 } | 2946 } |
2963 } | 2947 } |
2964 } else if (call_type == Call::SUPER_CALL) { | 2948 } else if (call_type == Call::SUPER_CALL) { |
2965 EmitSuperConstructorCall(expr); | 2949 EmitSuperConstructorCall(expr); |
2966 } else { | 2950 } else { |
2967 DCHECK(call_type == Call::OTHER_CALL); | 2951 DCHECK(call_type == Call::OTHER_CALL); |
2968 // Call to an arbitrary expression not handled specially above. | 2952 // Call to an arbitrary expression not handled specially above. |
2969 { PreservePositionScope scope(masm()->positions_recorder()); | |
2970 VisitForStackValue(callee); | 2953 VisitForStackValue(callee); |
2971 } | |
2972 __ LoadRoot(x1, Heap::kUndefinedValueRootIndex); | 2954 __ LoadRoot(x1, Heap::kUndefinedValueRootIndex); |
2973 __ Push(x1); | 2955 __ Push(x1); |
2974 // Emit function call. | 2956 // Emit function call. |
2975 EmitCall(expr); | 2957 EmitCall(expr); |
2976 } | 2958 } |
2977 | 2959 |
2978 #ifdef DEBUG | 2960 #ifdef DEBUG |
2979 // RecordJSReturnSite should have been called. | 2961 // RecordJSReturnSite should have been called. |
2980 DCHECK(expr->return_is_recorded_); | 2962 DCHECK(expr->return_is_recorded_); |
2981 #endif | 2963 #endif |
(...skipping 14 matching lines...) Expand all Loading... |
2996 | 2978 |
2997 // Push the arguments ("left-to-right") on the stack. | 2979 // Push the arguments ("left-to-right") on the stack. |
2998 ZoneList<Expression*>* args = expr->arguments(); | 2980 ZoneList<Expression*>* args = expr->arguments(); |
2999 int arg_count = args->length(); | 2981 int arg_count = args->length(); |
3000 for (int i = 0; i < arg_count; i++) { | 2982 for (int i = 0; i < arg_count; i++) { |
3001 VisitForStackValue(args->at(i)); | 2983 VisitForStackValue(args->at(i)); |
3002 } | 2984 } |
3003 | 2985 |
3004 // Call the construct call builtin that handles allocation and | 2986 // Call the construct call builtin that handles allocation and |
3005 // constructor invocation. | 2987 // constructor invocation. |
3006 SetSourcePosition(expr->position()); | 2988 SetExpressionPosition(expr); |
3007 | 2989 |
3008 // Load function and argument count into x1 and x0. | 2990 // Load function and argument count into x1 and x0. |
3009 __ Mov(x0, arg_count); | 2991 __ Mov(x0, arg_count); |
3010 __ Peek(x1, arg_count * kXRegSize); | 2992 __ Peek(x1, arg_count * kXRegSize); |
3011 | 2993 |
3012 // Record call targets in unoptimized code. | 2994 // Record call targets in unoptimized code. |
3013 if (FLAG_pretenuring_call_new) { | 2995 if (FLAG_pretenuring_call_new) { |
3014 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); | 2996 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); |
3015 DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() == | 2997 DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() == |
3016 expr->CallNewFeedbackSlot().ToInt() + 1); | 2998 expr->CallNewFeedbackSlot().ToInt() + 1); |
(...skipping 22 matching lines...) Expand all Loading... |
3039 | 3021 |
3040 // Push the arguments ("left-to-right") on the stack. | 3022 // Push the arguments ("left-to-right") on the stack. |
3041 ZoneList<Expression*>* args = expr->arguments(); | 3023 ZoneList<Expression*>* args = expr->arguments(); |
3042 int arg_count = args->length(); | 3024 int arg_count = args->length(); |
3043 for (int i = 0; i < arg_count; i++) { | 3025 for (int i = 0; i < arg_count; i++) { |
3044 VisitForStackValue(args->at(i)); | 3026 VisitForStackValue(args->at(i)); |
3045 } | 3027 } |
3046 | 3028 |
3047 // Call the construct call builtin that handles allocation and | 3029 // Call the construct call builtin that handles allocation and |
3048 // constructor invocation. | 3030 // constructor invocation. |
3049 SetSourcePosition(expr->position()); | 3031 SetExpressionPosition(expr); |
3050 | 3032 |
3051 // Load function and argument count into x1 and x0. | 3033 // Load function and argument count into x1 and x0. |
3052 __ Mov(x0, arg_count); | 3034 __ Mov(x0, arg_count); |
3053 __ Peek(x1, arg_count * kXRegSize); | 3035 __ Peek(x1, arg_count * kXRegSize); |
3054 | 3036 |
3055 // Record call targets in unoptimized code. | 3037 // Record call targets in unoptimized code. |
3056 if (FLAG_pretenuring_call_new) { | 3038 if (FLAG_pretenuring_call_new) { |
3057 UNREACHABLE(); | 3039 UNREACHABLE(); |
3058 /* TODO(dslomov): support pretenuring. | 3040 /* TODO(dslomov): support pretenuring. |
3059 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); | 3041 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); |
(...skipping 1359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4419 __ Mov(LoadDescriptor::SlotRegister(), | 4401 __ Mov(LoadDescriptor::SlotRegister(), |
4420 SmiFromSlot(expr->CallRuntimeFeedbackSlot())); | 4402 SmiFromSlot(expr->CallRuntimeFeedbackSlot())); |
4421 CallLoadIC(NOT_CONTEXTUAL); | 4403 CallLoadIC(NOT_CONTEXTUAL); |
4422 } | 4404 } |
4423 | 4405 |
4424 | 4406 |
4425 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 4407 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
4426 ZoneList<Expression*>* args = expr->arguments(); | 4408 ZoneList<Expression*>* args = expr->arguments(); |
4427 int arg_count = args->length(); | 4409 int arg_count = args->length(); |
4428 | 4410 |
4429 // Record source position of the IC call. | 4411 SetExpressionPosition(expr); |
4430 SetSourcePosition(expr->position()); | |
4431 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | 4412 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
4432 __ Peek(x1, (arg_count + 1) * kPointerSize); | 4413 __ Peek(x1, (arg_count + 1) * kPointerSize); |
4433 __ CallStub(&stub); | 4414 __ CallStub(&stub); |
4434 } | 4415 } |
4435 | 4416 |
4436 | 4417 |
4437 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 4418 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
4438 ZoneList<Expression*>* args = expr->arguments(); | 4419 ZoneList<Expression*>* args = expr->arguments(); |
4439 int arg_count = args->length(); | 4420 int arg_count = args->length(); |
4440 | 4421 |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4595 default: | 4576 default: |
4596 UNREACHABLE(); | 4577 UNREACHABLE(); |
4597 } | 4578 } |
4598 } | 4579 } |
4599 | 4580 |
4600 | 4581 |
4601 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4582 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
4602 DCHECK(expr->expression()->IsValidReferenceExpression()); | 4583 DCHECK(expr->expression()->IsValidReferenceExpression()); |
4603 | 4584 |
4604 Comment cmnt(masm_, "[ CountOperation"); | 4585 Comment cmnt(masm_, "[ CountOperation"); |
4605 SetSourcePosition(expr->position()); | |
4606 | 4586 |
4607 Property* prop = expr->expression()->AsProperty(); | 4587 Property* prop = expr->expression()->AsProperty(); |
4608 LhsKind assign_type = Property::GetAssignType(prop); | 4588 LhsKind assign_type = Property::GetAssignType(prop); |
4609 | 4589 |
4610 // Evaluate expression and get value. | 4590 // Evaluate expression and get value. |
4611 if (assign_type == VARIABLE) { | 4591 if (assign_type == VARIABLE) { |
4612 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4592 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
4613 AccumulatorValueContext context(this); | 4593 AccumulatorValueContext context(this); |
4614 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4594 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
4615 } else { | 4595 } else { |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4746 __ Poke(x0, 3 * kXRegSize); | 4726 __ Poke(x0, 3 * kXRegSize); |
4747 break; | 4727 break; |
4748 } | 4728 } |
4749 } | 4729 } |
4750 } | 4730 } |
4751 | 4731 |
4752 __ Bind(&stub_call); | 4732 __ Bind(&stub_call); |
4753 __ Mov(x1, x0); | 4733 __ Mov(x1, x0); |
4754 __ Mov(x0, Smi::FromInt(count_value)); | 4734 __ Mov(x0, Smi::FromInt(count_value)); |
4755 | 4735 |
4756 // Record position before stub call. | 4736 SetExpressionPosition(expr); |
4757 SetSourcePosition(expr->position()); | |
4758 | 4737 |
4759 { | 4738 { |
4760 Assembler::BlockPoolsScope scope(masm_); | 4739 Assembler::BlockPoolsScope scope(masm_); |
4761 Handle<Code> code = | 4740 Handle<Code> code = |
4762 CodeFactory::BinaryOpIC(isolate(), Token::ADD, | 4741 CodeFactory::BinaryOpIC(isolate(), Token::ADD, |
4763 strength(language_mode())).code(); | 4742 strength(language_mode())).code(); |
4764 CallIC(code, expr->CountBinOpFeedbackId()); | 4743 CallIC(code, expr->CountBinOpFeedbackId()); |
4765 patch_site.EmitPatchInfo(); | 4744 patch_site.EmitPatchInfo(); |
4766 } | 4745 } |
4767 __ Bind(&done); | 4746 __ Bind(&done); |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4974 } else { | 4953 } else { |
4975 ASM_LOCATION("FullCodeGenerator::EmitLiteralCompareTypeof other"); | 4954 ASM_LOCATION("FullCodeGenerator::EmitLiteralCompareTypeof other"); |
4976 if (if_false != fall_through) __ B(if_false); | 4955 if (if_false != fall_through) __ B(if_false); |
4977 } | 4956 } |
4978 context()->Plug(if_true, if_false); | 4957 context()->Plug(if_true, if_false); |
4979 } | 4958 } |
4980 | 4959 |
4981 | 4960 |
4982 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { | 4961 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { |
4983 Comment cmnt(masm_, "[ CompareOperation"); | 4962 Comment cmnt(masm_, "[ CompareOperation"); |
4984 SetSourcePosition(expr->position()); | 4963 SetExpressionPosition(expr); |
4985 | 4964 |
4986 // Try to generate an optimized comparison with a literal value. | 4965 // Try to generate an optimized comparison with a literal value. |
4987 // TODO(jbramley): This only checks common values like NaN or undefined. | 4966 // TODO(jbramley): This only checks common values like NaN or undefined. |
4988 // Should it also handle ARM64 immediate operands? | 4967 // Should it also handle ARM64 immediate operands? |
4989 if (TryLiteralCompare(expr)) { | 4968 if (TryLiteralCompare(expr)) { |
4990 return; | 4969 return; |
4991 } | 4970 } |
4992 | 4971 |
4993 // Assign labels according to context()->PrepareTest. | 4972 // Assign labels according to context()->PrepareTest. |
4994 Label materialize_true; | 4973 Label materialize_true; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5029 | 5008 |
5030 JumpPatchSite patch_site(masm_); | 5009 JumpPatchSite patch_site(masm_); |
5031 if (ShouldInlineSmiCase(op)) { | 5010 if (ShouldInlineSmiCase(op)) { |
5032 Label slow_case; | 5011 Label slow_case; |
5033 patch_site.EmitJumpIfEitherNotSmi(x0, x1, &slow_case); | 5012 patch_site.EmitJumpIfEitherNotSmi(x0, x1, &slow_case); |
5034 __ Cmp(x1, x0); | 5013 __ Cmp(x1, x0); |
5035 Split(cond, if_true, if_false, NULL); | 5014 Split(cond, if_true, if_false, NULL); |
5036 __ Bind(&slow_case); | 5015 __ Bind(&slow_case); |
5037 } | 5016 } |
5038 | 5017 |
5039 // Record position and call the compare IC. | |
5040 SetSourcePosition(expr->position()); | |
5041 Handle<Code> ic = CodeFactory::CompareIC( | 5018 Handle<Code> ic = CodeFactory::CompareIC( |
5042 isolate(), op, strength(language_mode())).code(); | 5019 isolate(), op, strength(language_mode())).code(); |
5043 CallIC(ic, expr->CompareOperationFeedbackId()); | 5020 CallIC(ic, expr->CompareOperationFeedbackId()); |
5044 patch_site.EmitPatchInfo(); | 5021 patch_site.EmitPatchInfo(); |
5045 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 5022 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
5046 __ CompareAndSplit(x0, 0, cond, if_true, if_false, fall_through); | 5023 __ CompareAndSplit(x0, 0, cond, if_true, if_false, fall_through); |
5047 } | 5024 } |
5048 } | 5025 } |
5049 | 5026 |
5050 // Convert the result of the comparison into one expected for this | 5027 // Convert the result of the comparison into one expected for this |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5084 | 5061 |
5085 | 5062 |
5086 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { | 5063 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { |
5087 __ Ldr(x0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 5064 __ Ldr(x0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
5088 context()->Plug(x0); | 5065 context()->Plug(x0); |
5089 } | 5066 } |
5090 | 5067 |
5091 | 5068 |
5092 void FullCodeGenerator::VisitYield(Yield* expr) { | 5069 void FullCodeGenerator::VisitYield(Yield* expr) { |
5093 Comment cmnt(masm_, "[ Yield"); | 5070 Comment cmnt(masm_, "[ Yield"); |
| 5071 SetExpressionPosition(expr); |
| 5072 |
5094 // Evaluate yielded value first; the initial iterator definition depends on | 5073 // Evaluate yielded value first; the initial iterator definition depends on |
5095 // this. It stays on the stack while we update the iterator. | 5074 // this. It stays on the stack while we update the iterator. |
5096 VisitForStackValue(expr->expression()); | 5075 VisitForStackValue(expr->expression()); |
5097 | 5076 |
5098 // TODO(jbramley): Tidy this up once the merge is done, using named registers | 5077 // TODO(jbramley): Tidy this up once the merge is done, using named registers |
5099 // and suchlike. The implementation changes a little by bleeding_edge so I | 5078 // and suchlike. The implementation changes a little by bleeding_edge so I |
5100 // don't want to spend too much time on it now. | 5079 // don't want to spend too much time on it now. |
5101 | 5080 |
5102 switch (expr->yield_kind()) { | 5081 switch (expr->yield_kind()) { |
5103 case Yield::kSuspend: | 5082 case Yield::kSuspend: |
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5611 } | 5590 } |
5612 | 5591 |
5613 return INTERRUPT; | 5592 return INTERRUPT; |
5614 } | 5593 } |
5615 | 5594 |
5616 | 5595 |
5617 } // namespace internal | 5596 } // namespace internal |
5618 } // namespace v8 | 5597 } // namespace v8 |
5619 | 5598 |
5620 #endif // V8_TARGET_ARCH_ARM64 | 5599 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |