| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_MIPS64 | 7 #if V8_TARGET_ARCH_MIPS64 |
| 8 | 8 |
| 9 // Note on Mips implementation: | 9 // Note on Mips implementation: |
| 10 // | 10 // |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 RelocInfo::CODE_TARGET); | 488 RelocInfo::CODE_TARGET); |
| 489 __ pop(v0); | 489 __ pop(v0); |
| 490 EmitProfilingCounterReset(); | 490 EmitProfilingCounterReset(); |
| 491 __ bind(&ok); | 491 __ bind(&ok); |
| 492 | 492 |
| 493 #ifdef DEBUG | 493 #ifdef DEBUG |
| 494 // Add a label for checking the size of the code used for returning. | 494 // Add a label for checking the size of the code used for returning. |
| 495 Label check_exit_codesize; | 495 Label check_exit_codesize; |
| 496 masm_->bind(&check_exit_codesize); | 496 masm_->bind(&check_exit_codesize); |
| 497 #endif | 497 #endif |
| 498 |
| 498 // Make sure that the constant pool is not emitted inside of the return | 499 // Make sure that the constant pool is not emitted inside of the return |
| 499 // sequence. | 500 // sequence. |
| 500 { Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); | 501 { Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); |
| 501 // Here we use masm_-> instead of the __ macro to avoid the code coverage | 502 // Here we use masm_-> instead of the __ macro to avoid the code coverage |
| 502 // tool from instrumenting as we rely on the code size here. | 503 // tool from instrumenting as we rely on the code size here. |
| 503 int32_t arg_count = info_->scope()->num_parameters() + 1; | 504 int32_t arg_count = info_->scope()->num_parameters() + 1; |
| 504 int32_t sp_delta = arg_count * kPointerSize; | 505 int32_t sp_delta = arg_count * kPointerSize; |
| 505 CodeGenerator::RecordPositions(masm_, function()->end_position() - 1); | 506 SetReturnPosition(function()); |
| 506 __ RecordJSReturn(); | 507 __ RecordJSReturn(); |
| 507 masm_->mov(sp, fp); | 508 masm_->mov(sp, fp); |
| 508 int no_frame_start = masm_->pc_offset(); | 509 int no_frame_start = masm_->pc_offset(); |
| 509 masm_->MultiPop(static_cast<RegList>(fp.bit() | ra.bit())); | 510 masm_->MultiPop(static_cast<RegList>(fp.bit() | ra.bit())); |
| 510 masm_->Daddu(sp, sp, Operand(sp_delta)); | 511 masm_->Daddu(sp, sp, Operand(sp_delta)); |
| 511 masm_->Jump(ra); | 512 masm_->Jump(ra); |
| 512 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); | 513 info_->AddNoFrameRange(no_frame_start, masm_->pc_offset()); |
| 513 } | 514 } |
| 514 | 515 |
| 515 #ifdef DEBUG | 516 #ifdef DEBUG |
| (...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1071 patch_site.EmitJumpIfNotSmi(a2, &slow_case); | 1072 patch_site.EmitJumpIfNotSmi(a2, &slow_case); |
| 1072 | 1073 |
| 1073 __ Branch(&next_test, ne, a1, Operand(a0)); | 1074 __ Branch(&next_test, ne, a1, Operand(a0)); |
| 1074 __ Drop(1); // Switch value is no longer needed. | 1075 __ Drop(1); // Switch value is no longer needed. |
| 1075 __ Branch(clause->body_target()); | 1076 __ Branch(clause->body_target()); |
| 1076 | 1077 |
| 1077 __ bind(&slow_case); | 1078 __ bind(&slow_case); |
| 1078 } | 1079 } |
| 1079 | 1080 |
| 1080 // Record position before stub call for type feedback. | 1081 // Record position before stub call for type feedback. |
| 1081 SetSourcePosition(clause->position()); | 1082 SetExpressionPosition(clause); |
| 1082 Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT, | 1083 Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT, |
| 1083 strength(language_mode())).code(); | 1084 strength(language_mode())).code(); |
| 1084 CallIC(ic, clause->CompareId()); | 1085 CallIC(ic, clause->CompareId()); |
| 1085 patch_site.EmitPatchInfo(); | 1086 patch_site.EmitPatchInfo(); |
| 1086 | 1087 |
| 1087 Label skip; | 1088 Label skip; |
| 1088 __ Branch(&skip); | 1089 __ Branch(&skip); |
| 1089 PrepareForBailout(clause, TOS_REG); | 1090 PrepareForBailout(clause, TOS_REG); |
| 1090 __ LoadRoot(at, Heap::kTrueValueRootIndex); | 1091 __ LoadRoot(at, Heap::kTrueValueRootIndex); |
| 1091 __ Branch(&next_test, ne, v0, Operand(at)); | 1092 __ Branch(&next_test, ne, v0, Operand(at)); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1117 VisitStatements(clause->statements()); | 1118 VisitStatements(clause->statements()); |
| 1118 } | 1119 } |
| 1119 | 1120 |
| 1120 __ bind(nested_statement.break_label()); | 1121 __ bind(nested_statement.break_label()); |
| 1121 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 1122 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
| 1122 } | 1123 } |
| 1123 | 1124 |
| 1124 | 1125 |
| 1125 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { | 1126 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
| 1126 Comment cmnt(masm_, "[ ForInStatement"); | 1127 Comment cmnt(masm_, "[ ForInStatement"); |
| 1128 SetStatementPosition(stmt, SKIP_BREAK); |
| 1129 |
| 1127 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); | 1130 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); |
| 1128 SetStatementPosition(stmt); | |
| 1129 | 1131 |
| 1130 Label loop, exit; | 1132 Label loop, exit; |
| 1131 ForIn loop_statement(this, stmt); | 1133 ForIn loop_statement(this, stmt); |
| 1132 increment_loop_depth(); | 1134 increment_loop_depth(); |
| 1133 | 1135 |
| 1134 // Get the object to enumerate over. If the object is null or undefined, skip | 1136 // Get the object to enumerate over. If the object is null or undefined, skip |
| 1135 // over the loop. See ECMA-262 version 5, section 12.6.4. | 1137 // over the loop. See ECMA-262 version 5, section 12.6.4. |
| 1136 SetExpressionPosition(stmt->enumerable()); | 1138 SetExpressionAsStatementPosition(stmt->enumerable()); |
| 1137 VisitForAccumulatorValue(stmt->enumerable()); | 1139 VisitForAccumulatorValue(stmt->enumerable()); |
| 1138 __ mov(a0, result_register()); // Result as param to InvokeBuiltin below. | 1140 __ mov(a0, result_register()); // Result as param to InvokeBuiltin below. |
| 1139 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 1141 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
| 1140 __ Branch(&exit, eq, a0, Operand(at)); | 1142 __ Branch(&exit, eq, a0, Operand(at)); |
| 1141 Register null_value = a5; | 1143 Register null_value = a5; |
| 1142 __ LoadRoot(null_value, Heap::kNullValueRootIndex); | 1144 __ LoadRoot(null_value, Heap::kNullValueRootIndex); |
| 1143 __ Branch(&exit, eq, a0, Operand(null_value)); | 1145 __ Branch(&exit, eq, a0, Operand(null_value)); |
| 1144 PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); | 1146 PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); |
| 1145 __ mov(a0, v0); | 1147 __ mov(a0, v0); |
| 1146 // Convert the object to a JS object. | 1148 // Convert the object to a JS object. |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1226 __ li(a1, Operand(Smi::FromInt(0))); // Zero indicates proxy | 1228 __ li(a1, Operand(Smi::FromInt(0))); // Zero indicates proxy |
| 1227 __ bind(&non_proxy); | 1229 __ bind(&non_proxy); |
| 1228 __ Push(a1, v0); // Smi and array | 1230 __ Push(a1, v0); // Smi and array |
| 1229 __ ld(a1, FieldMemOperand(v0, FixedArray::kLengthOffset)); | 1231 __ ld(a1, FieldMemOperand(v0, FixedArray::kLengthOffset)); |
| 1230 __ li(a0, Operand(Smi::FromInt(0))); | 1232 __ li(a0, Operand(Smi::FromInt(0))); |
| 1231 __ Push(a1, a0); // Fixed array length (as smi) and initial index. | 1233 __ Push(a1, a0); // Fixed array length (as smi) and initial index. |
| 1232 | 1234 |
| 1233 // Generate code for doing the condition check. | 1235 // Generate code for doing the condition check. |
| 1234 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); | 1236 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); |
| 1235 __ bind(&loop); | 1237 __ bind(&loop); |
| 1236 SetExpressionPosition(stmt->each()); | 1238 SetExpressionAsStatementPosition(stmt->each()); |
| 1237 | 1239 |
| 1238 // Load the current count to a0, load the length to a1. | 1240 // Load the current count to a0, load the length to a1. |
| 1239 __ ld(a0, MemOperand(sp, 0 * kPointerSize)); | 1241 __ ld(a0, MemOperand(sp, 0 * kPointerSize)); |
| 1240 __ ld(a1, MemOperand(sp, 1 * kPointerSize)); | 1242 __ ld(a1, MemOperand(sp, 1 * kPointerSize)); |
| 1241 __ Branch(loop_statement.break_label(), hs, a0, Operand(a1)); | 1243 __ Branch(loop_statement.break_label(), hs, a0, Operand(a1)); |
| 1242 | 1244 |
| 1243 // Get the current entry of the array into register a3. | 1245 // Get the current entry of the array into register a3. |
| 1244 __ ld(a2, MemOperand(sp, 2 * kPointerSize)); | 1246 __ ld(a2, MemOperand(sp, 2 * kPointerSize)); |
| 1245 __ Daddu(a2, a2, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 1247 __ Daddu(a2, a2, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| 1246 __ SmiScale(a4, a0, kPointerSizeLog2); | 1248 __ SmiScale(a4, a0, kPointerSizeLog2); |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1472 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 1474 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 1473 } | 1475 } |
| 1474 } | 1476 } |
| 1475 __ Branch(done); | 1477 __ Branch(done); |
| 1476 } | 1478 } |
| 1477 } | 1479 } |
| 1478 | 1480 |
| 1479 | 1481 |
| 1480 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { | 1482 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
| 1481 // Record position before possible IC call. | 1483 // Record position before possible IC call. |
| 1482 SetSourcePosition(proxy->position()); | 1484 SetExpressionPosition(proxy); |
| 1483 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); | 1485 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); |
| 1484 Variable* var = proxy->var(); | 1486 Variable* var = proxy->var(); |
| 1485 | 1487 |
| 1486 // Three cases: global variables, lookup variables, and all other types of | 1488 // Three cases: global variables, lookup variables, and all other types of |
| 1487 // variables. | 1489 // variables. |
| 1488 switch (var->location()) { | 1490 switch (var->location()) { |
| 1489 case Variable::UNALLOCATED: { | 1491 case Variable::UNALLOCATED: { |
| 1490 Comment cmnt(masm_, "[ Global variable"); | 1492 Comment cmnt(masm_, "[ Global variable"); |
| 1491 // Use inline caching. Variable name is passed in a2 and the global | 1493 // Use inline caching. Variable name is passed in a2 and the global |
| 1492 // object (receiver) in a0. | 1494 // object (receiver) in a0. |
| (...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1971 } else { | 1973 } else { |
| 1972 context()->Plug(v0); | 1974 context()->Plug(v0); |
| 1973 } | 1975 } |
| 1974 } | 1976 } |
| 1975 | 1977 |
| 1976 | 1978 |
| 1977 void FullCodeGenerator::VisitAssignment(Assignment* expr) { | 1979 void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
| 1978 DCHECK(expr->target()->IsValidReferenceExpression()); | 1980 DCHECK(expr->target()->IsValidReferenceExpression()); |
| 1979 | 1981 |
| 1980 Comment cmnt(masm_, "[ Assignment"); | 1982 Comment cmnt(masm_, "[ Assignment"); |
| 1983 SetExpressionPosition(expr, INSERT_BREAK); |
| 1981 | 1984 |
| 1982 Property* property = expr->target()->AsProperty(); | 1985 Property* property = expr->target()->AsProperty(); |
| 1983 LhsKind assign_type = Property::GetAssignType(property); | 1986 LhsKind assign_type = Property::GetAssignType(property); |
| 1984 | 1987 |
| 1985 // Evaluate LHS expression. | 1988 // Evaluate LHS expression. |
| 1986 switch (assign_type) { | 1989 switch (assign_type) { |
| 1987 case VARIABLE: | 1990 case VARIABLE: |
| 1988 // Nothing to do here. | 1991 // Nothing to do here. |
| 1989 break; | 1992 break; |
| 1990 case NAMED_PROPERTY: | 1993 case NAMED_PROPERTY: |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2064 EmitKeyedPropertyLoad(property); | 2067 EmitKeyedPropertyLoad(property); |
| 2065 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 2068 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
| 2066 break; | 2069 break; |
| 2067 } | 2070 } |
| 2068 } | 2071 } |
| 2069 | 2072 |
| 2070 Token::Value op = expr->binary_op(); | 2073 Token::Value op = expr->binary_op(); |
| 2071 __ push(v0); // Left operand goes on the stack. | 2074 __ push(v0); // Left operand goes on the stack. |
| 2072 VisitForAccumulatorValue(expr->value()); | 2075 VisitForAccumulatorValue(expr->value()); |
| 2073 | 2076 |
| 2074 SetSourcePosition(expr->position() + 1); | |
| 2075 AccumulatorValueContext context(this); | 2077 AccumulatorValueContext context(this); |
| 2076 if (ShouldInlineSmiCase(op)) { | 2078 if (ShouldInlineSmiCase(op)) { |
| 2077 EmitInlineSmiBinaryOp(expr->binary_operation(), | 2079 EmitInlineSmiBinaryOp(expr->binary_operation(), |
| 2078 op, | 2080 op, |
| 2079 expr->target(), | 2081 expr->target(), |
| 2080 expr->value()); | 2082 expr->value()); |
| 2081 } else { | 2083 } else { |
| 2082 EmitBinaryOp(expr->binary_operation(), op); | 2084 EmitBinaryOp(expr->binary_operation(), op); |
| 2083 } | 2085 } |
| 2084 | 2086 |
| 2085 // Deoptimization point in case the binary operation may have side effects. | 2087 // Deoptimization point in case the binary operation may have side effects. |
| 2086 PrepareForBailout(expr->binary_operation(), TOS_REG); | 2088 PrepareForBailout(expr->binary_operation(), TOS_REG); |
| 2087 } else { | 2089 } else { |
| 2088 VisitForAccumulatorValue(expr->value()); | 2090 VisitForAccumulatorValue(expr->value()); |
| 2089 } | 2091 } |
| 2090 | 2092 |
| 2091 // Record source position before possible IC call. | 2093 SetExpressionPosition(expr); |
| 2092 SetSourcePosition(expr->position()); | |
| 2093 | 2094 |
| 2094 // Store the value. | 2095 // Store the value. |
| 2095 switch (assign_type) { | 2096 switch (assign_type) { |
| 2096 case VARIABLE: | 2097 case VARIABLE: |
| 2097 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 2098 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
| 2098 expr->op(), expr->AssignmentSlot()); | 2099 expr->op(), expr->AssignmentSlot()); |
| 2099 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2100 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2100 context()->Plug(v0); | 2101 context()->Plug(v0); |
| 2101 break; | 2102 break; |
| 2102 case NAMED_PROPERTY: | 2103 case NAMED_PROPERTY: |
| 2103 EmitNamedPropertyAssignment(expr); | 2104 EmitNamedPropertyAssignment(expr); |
| 2104 break; | 2105 break; |
| 2105 case NAMED_SUPER_PROPERTY: | 2106 case NAMED_SUPER_PROPERTY: |
| 2106 EmitNamedSuperPropertyStore(property); | 2107 EmitNamedSuperPropertyStore(property); |
| 2107 context()->Plug(v0); | 2108 context()->Plug(v0); |
| 2108 break; | 2109 break; |
| 2109 case KEYED_SUPER_PROPERTY: | 2110 case KEYED_SUPER_PROPERTY: |
| 2110 EmitKeyedSuperPropertyStore(property); | 2111 EmitKeyedSuperPropertyStore(property); |
| 2111 context()->Plug(v0); | 2112 context()->Plug(v0); |
| 2112 break; | 2113 break; |
| 2113 case KEYED_PROPERTY: | 2114 case KEYED_PROPERTY: |
| 2114 EmitKeyedPropertyAssignment(expr); | 2115 EmitKeyedPropertyAssignment(expr); |
| 2115 break; | 2116 break; |
| 2116 } | 2117 } |
| 2117 } | 2118 } |
| 2118 | 2119 |
| 2119 | 2120 |
| 2120 void FullCodeGenerator::VisitYield(Yield* expr) { | 2121 void FullCodeGenerator::VisitYield(Yield* expr) { |
| 2121 Comment cmnt(masm_, "[ Yield"); | 2122 Comment cmnt(masm_, "[ Yield"); |
| 2123 SetExpressionPosition(expr); |
| 2124 |
| 2122 // Evaluate yielded value first; the initial iterator definition depends on | 2125 // Evaluate yielded value first; the initial iterator definition depends on |
| 2123 // this. It stays on the stack while we update the iterator. | 2126 // this. It stays on the stack while we update the iterator. |
| 2124 VisitForStackValue(expr->expression()); | 2127 VisitForStackValue(expr->expression()); |
| 2125 | 2128 |
| 2126 switch (expr->yield_kind()) { | 2129 switch (expr->yield_kind()) { |
| 2127 case Yield::kSuspend: | 2130 case Yield::kSuspend: |
| 2128 // Pop value from top-of-stack slot; box result into result register. | 2131 // Pop value from top-of-stack slot; box result into result register. |
| 2129 EmitCreateIteratorResult(false); | 2132 EmitCreateIteratorResult(false); |
| 2130 __ push(result_register()); | 2133 __ push(result_register()); |
| 2131 // Fall through. | 2134 // Fall through. |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2399 FieldMemOperand(v0, JSGeneratorObject::kResultDonePropertyOffset)); | 2402 FieldMemOperand(v0, JSGeneratorObject::kResultDonePropertyOffset)); |
| 2400 | 2403 |
| 2401 // Only the value field needs a write barrier, as the other values are in the | 2404 // Only the value field needs a write barrier, as the other values are in the |
| 2402 // root set. | 2405 // root set. |
| 2403 __ RecordWriteField(v0, JSGeneratorObject::kResultValuePropertyOffset, | 2406 __ RecordWriteField(v0, JSGeneratorObject::kResultValuePropertyOffset, |
| 2404 a2, a3, kRAHasBeenSaved, kDontSaveFPRegs); | 2407 a2, a3, kRAHasBeenSaved, kDontSaveFPRegs); |
| 2405 } | 2408 } |
| 2406 | 2409 |
| 2407 | 2410 |
| 2408 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2411 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 2409 SetSourcePosition(prop->position()); | 2412 SetExpressionPosition(prop); |
| 2410 Literal* key = prop->key()->AsLiteral(); | 2413 Literal* key = prop->key()->AsLiteral(); |
| 2411 DCHECK(!prop->IsSuperAccess()); | 2414 DCHECK(!prop->IsSuperAccess()); |
| 2412 | 2415 |
| 2413 __ li(LoadDescriptor::NameRegister(), Operand(key->value())); | 2416 __ li(LoadDescriptor::NameRegister(), Operand(key->value())); |
| 2414 __ li(LoadDescriptor::SlotRegister(), | 2417 __ li(LoadDescriptor::SlotRegister(), |
| 2415 Operand(SmiFromSlot(prop->PropertyFeedbackSlot()))); | 2418 Operand(SmiFromSlot(prop->PropertyFeedbackSlot()))); |
| 2416 CallLoadIC(NOT_CONTEXTUAL, language_mode()); | 2419 CallLoadIC(NOT_CONTEXTUAL, language_mode()); |
| 2417 } | 2420 } |
| 2418 | 2421 |
| 2419 | 2422 |
| 2420 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { | 2423 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { |
| 2421 // Stack: receiver, home_object. | 2424 // Stack: receiver, home_object. |
| 2422 SetSourcePosition(prop->position()); | 2425 SetExpressionPosition(prop); |
| 2426 |
| 2423 Literal* key = prop->key()->AsLiteral(); | 2427 Literal* key = prop->key()->AsLiteral(); |
| 2424 DCHECK(!key->value()->IsSmi()); | 2428 DCHECK(!key->value()->IsSmi()); |
| 2425 DCHECK(prop->IsSuperAccess()); | 2429 DCHECK(prop->IsSuperAccess()); |
| 2426 | 2430 |
| 2427 __ Push(key->value()); | 2431 __ Push(key->value()); |
| 2428 __ Push(Smi::FromInt(language_mode())); | 2432 __ Push(Smi::FromInt(language_mode())); |
| 2429 __ CallRuntime(Runtime::kLoadFromSuper, 4); | 2433 __ CallRuntime(Runtime::kLoadFromSuper, 4); |
| 2430 } | 2434 } |
| 2431 | 2435 |
| 2432 | 2436 |
| 2433 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2437 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 2434 SetSourcePosition(prop->position()); | |
| 2435 // Call keyed load IC. It has register arguments receiver and key. | 2438 // Call keyed load IC. It has register arguments receiver and key. |
| 2439 SetExpressionPosition(prop); |
| 2440 |
| 2436 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code(); | 2441 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code(); |
| 2437 __ li(LoadDescriptor::SlotRegister(), | 2442 __ li(LoadDescriptor::SlotRegister(), |
| 2438 Operand(SmiFromSlot(prop->PropertyFeedbackSlot()))); | 2443 Operand(SmiFromSlot(prop->PropertyFeedbackSlot()))); |
| 2439 CallIC(ic); | 2444 CallIC(ic); |
| 2440 } | 2445 } |
| 2441 | 2446 |
| 2442 | 2447 |
| 2443 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { | 2448 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { |
| 2444 // Stack: receiver, home_object, key. | 2449 // Stack: receiver, home_object, key. |
| 2450 SetExpressionPosition(prop); |
| 2445 __ Push(Smi::FromInt(language_mode())); | 2451 __ Push(Smi::FromInt(language_mode())); |
| 2446 SetSourcePosition(prop->position()); | |
| 2447 | |
| 2448 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); | 2452 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); |
| 2449 } | 2453 } |
| 2450 | 2454 |
| 2451 | 2455 |
| 2452 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2456 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
| 2453 Token::Value op, | 2457 Token::Value op, |
| 2454 Expression* left_expr, | 2458 Expression* left_expr, |
| 2455 Expression* right_expr) { | 2459 Expression* right_expr) { |
| 2456 Label done, smi_case, stub_call; | 2460 Label done, smi_case, stub_call; |
| 2457 | 2461 |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2807 if (is_strict(language_mode())) { | 2811 if (is_strict(language_mode())) { |
| 2808 __ CallRuntime(Runtime::kThrowConstAssignError, 0); | 2812 __ CallRuntime(Runtime::kThrowConstAssignError, 0); |
| 2809 } | 2813 } |
| 2810 // Silently ignore store in sloppy mode. | 2814 // Silently ignore store in sloppy mode. |
| 2811 } | 2815 } |
| 2812 } | 2816 } |
| 2813 | 2817 |
| 2814 | 2818 |
| 2815 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2819 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
| 2816 // Assignment to a property, using a named store IC. | 2820 // Assignment to a property, using a named store IC. |
| 2821 SetExpressionPosition(expr); |
| 2817 Property* prop = expr->target()->AsProperty(); | 2822 Property* prop = expr->target()->AsProperty(); |
| 2818 DCHECK(prop != NULL); | 2823 DCHECK(prop != NULL); |
| 2819 DCHECK(prop->key()->IsLiteral()); | 2824 DCHECK(prop->key()->IsLiteral()); |
| 2820 | 2825 |
| 2821 // Record source code position before IC call. | |
| 2822 SetSourcePosition(expr->position()); | |
| 2823 __ mov(StoreDescriptor::ValueRegister(), result_register()); | 2826 __ mov(StoreDescriptor::ValueRegister(), result_register()); |
| 2824 __ li(StoreDescriptor::NameRegister(), | 2827 __ li(StoreDescriptor::NameRegister(), |
| 2825 Operand(prop->key()->AsLiteral()->value())); | 2828 Operand(prop->key()->AsLiteral()->value())); |
| 2826 __ pop(StoreDescriptor::ReceiverRegister()); | 2829 __ pop(StoreDescriptor::ReceiverRegister()); |
| 2827 if (FLAG_vector_stores) { | 2830 if (FLAG_vector_stores) { |
| 2828 EmitLoadStoreICSlot(expr->AssignmentSlot()); | 2831 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2829 CallStoreIC(); | 2832 CallStoreIC(); |
| 2830 } else { | 2833 } else { |
| 2831 CallStoreIC(expr->AssignmentFeedbackId()); | 2834 CallStoreIC(expr->AssignmentFeedbackId()); |
| 2832 } | 2835 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2861 __ Push(v0); | 2864 __ Push(v0); |
| 2862 __ CallRuntime( | 2865 __ CallRuntime( |
| 2863 (is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict | 2866 (is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
| 2864 : Runtime::kStoreKeyedToSuper_Sloppy), | 2867 : Runtime::kStoreKeyedToSuper_Sloppy), |
| 2865 4); | 2868 4); |
| 2866 } | 2869 } |
| 2867 | 2870 |
| 2868 | 2871 |
| 2869 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2872 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 2870 // Assignment to a property, using a keyed store IC. | 2873 // Assignment to a property, using a keyed store IC. |
| 2874 SetExpressionPosition(expr); |
| 2871 | 2875 |
| 2872 // Record source code position before IC call. | |
| 2873 SetSourcePosition(expr->position()); | |
| 2874 // Call keyed store IC. | 2876 // Call keyed store IC. |
| 2875 // The arguments are: | 2877 // The arguments are: |
| 2876 // - a0 is the value, | 2878 // - a0 is the value, |
| 2877 // - a1 is the key, | 2879 // - a1 is the key, |
| 2878 // - a2 is the receiver. | 2880 // - a2 is the receiver. |
| 2879 __ mov(StoreDescriptor::ValueRegister(), result_register()); | 2881 __ mov(StoreDescriptor::ValueRegister(), result_register()); |
| 2880 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); | 2882 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); |
| 2881 DCHECK(StoreDescriptor::ValueRegister().is(a0)); | 2883 DCHECK(StoreDescriptor::ValueRegister().is(a0)); |
| 2882 | 2884 |
| 2883 Handle<Code> ic = | 2885 Handle<Code> ic = |
| 2884 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2886 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 2885 if (FLAG_vector_stores) { | 2887 if (FLAG_vector_stores) { |
| 2886 EmitLoadStoreICSlot(expr->AssignmentSlot()); | 2888 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2887 CallIC(ic); | 2889 CallIC(ic); |
| 2888 } else { | 2890 } else { |
| 2889 CallIC(ic, expr->AssignmentFeedbackId()); | 2891 CallIC(ic, expr->AssignmentFeedbackId()); |
| 2890 } | 2892 } |
| 2891 | 2893 |
| 2892 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2894 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2893 context()->Plug(v0); | 2895 context()->Plug(v0); |
| 2894 } | 2896 } |
| 2895 | 2897 |
| 2896 | 2898 |
| 2897 void FullCodeGenerator::VisitProperty(Property* expr) { | 2899 void FullCodeGenerator::VisitProperty(Property* expr) { |
| 2898 Comment cmnt(masm_, "[ Property"); | 2900 Comment cmnt(masm_, "[ Property"); |
| 2901 SetExpressionPosition(expr); |
| 2902 |
| 2899 Expression* key = expr->key(); | 2903 Expression* key = expr->key(); |
| 2900 | 2904 |
| 2901 if (key->IsPropertyName()) { | 2905 if (key->IsPropertyName()) { |
| 2902 if (!expr->IsSuperAccess()) { | 2906 if (!expr->IsSuperAccess()) { |
| 2903 VisitForAccumulatorValue(expr->obj()); | 2907 VisitForAccumulatorValue(expr->obj()); |
| 2904 __ Move(LoadDescriptor::ReceiverRegister(), v0); | 2908 __ Move(LoadDescriptor::ReceiverRegister(), v0); |
| 2905 EmitNamedPropertyLoad(expr); | 2909 EmitNamedPropertyLoad(expr); |
| 2906 } else { | 2910 } else { |
| 2907 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); | 2911 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); |
| 2908 VisitForStackValue( | 2912 VisitForStackValue( |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2964 __ ld(at, MemOperand(sp, 0)); | 2968 __ ld(at, MemOperand(sp, 0)); |
| 2965 __ push(at); | 2969 __ push(at); |
| 2966 __ sd(v0, MemOperand(sp, kPointerSize)); | 2970 __ sd(v0, MemOperand(sp, kPointerSize)); |
| 2967 } | 2971 } |
| 2968 | 2972 |
| 2969 EmitCall(expr, call_type); | 2973 EmitCall(expr, call_type); |
| 2970 } | 2974 } |
| 2971 | 2975 |
| 2972 | 2976 |
| 2973 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | 2977 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { |
| 2978 SetExpressionPosition(expr); |
| 2974 Expression* callee = expr->expression(); | 2979 Expression* callee = expr->expression(); |
| 2975 DCHECK(callee->IsProperty()); | 2980 DCHECK(callee->IsProperty()); |
| 2976 Property* prop = callee->AsProperty(); | 2981 Property* prop = callee->AsProperty(); |
| 2977 DCHECK(prop->IsSuperAccess()); | 2982 DCHECK(prop->IsSuperAccess()); |
| 2978 | 2983 |
| 2979 SetSourcePosition(prop->position()); | |
| 2980 Literal* key = prop->key()->AsLiteral(); | 2984 Literal* key = prop->key()->AsLiteral(); |
| 2981 DCHECK(!key->value()->IsSmi()); | 2985 DCHECK(!key->value()->IsSmi()); |
| 2982 // Load the function from the receiver. | 2986 // Load the function from the receiver. |
| 2983 const Register scratch = a1; | 2987 const Register scratch = a1; |
| 2984 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | 2988 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); |
| 2985 VisitForAccumulatorValue(super_ref->home_object()); | 2989 VisitForAccumulatorValue(super_ref->home_object()); |
| 2986 __ mov(scratch, v0); | 2990 __ mov(scratch, v0); |
| 2987 VisitForAccumulatorValue(super_ref->this_var()); | 2991 VisitForAccumulatorValue(super_ref->this_var()); |
| 2988 __ Push(scratch, v0, v0, scratch); | 2992 __ Push(scratch, v0, v0, scratch); |
| 2989 __ Push(key->value()); | 2993 __ Push(key->value()); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3031 EmitCall(expr, CallICState::METHOD); | 3035 EmitCall(expr, CallICState::METHOD); |
| 3032 } | 3036 } |
| 3033 | 3037 |
| 3034 | 3038 |
| 3035 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | 3039 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { |
| 3036 Expression* callee = expr->expression(); | 3040 Expression* callee = expr->expression(); |
| 3037 DCHECK(callee->IsProperty()); | 3041 DCHECK(callee->IsProperty()); |
| 3038 Property* prop = callee->AsProperty(); | 3042 Property* prop = callee->AsProperty(); |
| 3039 DCHECK(prop->IsSuperAccess()); | 3043 DCHECK(prop->IsSuperAccess()); |
| 3040 | 3044 |
| 3041 SetSourcePosition(prop->position()); | 3045 SetExpressionPosition(prop); |
| 3042 // Load the function from the receiver. | 3046 // Load the function from the receiver. |
| 3043 const Register scratch = a1; | 3047 const Register scratch = a1; |
| 3044 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | 3048 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); |
| 3045 VisitForAccumulatorValue(super_ref->home_object()); | 3049 VisitForAccumulatorValue(super_ref->home_object()); |
| 3046 __ Move(scratch, v0); | 3050 __ Move(scratch, v0); |
| 3047 VisitForAccumulatorValue(super_ref->this_var()); | 3051 VisitForAccumulatorValue(super_ref->this_var()); |
| 3048 __ Push(scratch, v0, v0, scratch); | 3052 __ Push(scratch, v0, v0, scratch); |
| 3049 VisitForStackValue(prop->key()); | 3053 VisitForStackValue(prop->key()); |
| 3050 __ Push(Smi::FromInt(language_mode())); | 3054 __ Push(Smi::FromInt(language_mode())); |
| 3051 | 3055 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3065 // - target function | 3069 // - target function |
| 3066 // - this (receiver) | 3070 // - this (receiver) |
| 3067 EmitCall(expr, CallICState::METHOD); | 3071 EmitCall(expr, CallICState::METHOD); |
| 3068 } | 3072 } |
| 3069 | 3073 |
| 3070 | 3074 |
| 3071 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) { | 3075 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) { |
| 3072 // Load the arguments. | 3076 // Load the arguments. |
| 3073 ZoneList<Expression*>* args = expr->arguments(); | 3077 ZoneList<Expression*>* args = expr->arguments(); |
| 3074 int arg_count = args->length(); | 3078 int arg_count = args->length(); |
| 3075 { PreservePositionScope scope(masm()->positions_recorder()); | 3079 for (int i = 0; i < arg_count; i++) { |
| 3076 for (int i = 0; i < arg_count; i++) { | 3080 VisitForStackValue(args->at(i)); |
| 3077 VisitForStackValue(args->at(i)); | |
| 3078 } | |
| 3079 } | 3081 } |
| 3080 | 3082 |
| 3081 // Record source position of the IC call. | 3083 // Record source position of the IC call. |
| 3082 SetSourcePosition(expr->position()); | 3084 SetExpressionPosition(expr); |
| 3083 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code(); | 3085 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code(); |
| 3084 __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackICSlot()))); | 3086 __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackICSlot()))); |
| 3085 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 3087 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 3086 // Don't assign a type feedback id to the IC, since type feedback is provided | 3088 // Don't assign a type feedback id to the IC, since type feedback is provided |
| 3087 // by the vector above. | 3089 // by the vector above. |
| 3088 CallIC(ic); | 3090 CallIC(ic); |
| 3089 RecordJSReturnSite(expr); | 3091 RecordJSReturnSite(expr); |
| 3090 // Restore context register. | 3092 // Restore context register. |
| 3091 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3093 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 3092 context()->DropAndPlug(1, v0); | 3094 context()->DropAndPlug(1, v0); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3130 | 3132 |
| 3131 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); | 3133 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); |
| 3132 } | 3134 } |
| 3133 | 3135 |
| 3134 | 3136 |
| 3135 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. | 3137 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. |
| 3136 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { | 3138 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { |
| 3137 VariableProxy* callee = expr->expression()->AsVariableProxy(); | 3139 VariableProxy* callee = expr->expression()->AsVariableProxy(); |
| 3138 if (callee->var()->IsLookupSlot()) { | 3140 if (callee->var()->IsLookupSlot()) { |
| 3139 Label slow, done; | 3141 Label slow, done; |
| 3140 SetSourcePosition(callee->position()); | 3142 |
| 3141 { | 3143 SetExpressionPosition(callee); |
| 3142 PreservePositionScope scope(masm()->positions_recorder()); | 3144 // Generate code for loading from variables potentially shadowed by |
| 3143 // Generate code for loading from variables potentially shadowed | 3145 // eval-introduced variables. |
| 3144 // by eval-introduced variables. | 3146 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); |
| 3145 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); | |
| 3146 } | |
| 3147 | 3147 |
| 3148 __ bind(&slow); | 3148 __ bind(&slow); |
| 3149 // Call the runtime to find the function to call (returned in v0) | 3149 // Call the runtime to find the function to call (returned in v0) |
| 3150 // and the object holding it (returned in v1). | 3150 // and the object holding it (returned in v1). |
| 3151 DCHECK(!context_register().is(a2)); | 3151 DCHECK(!context_register().is(a2)); |
| 3152 __ li(a2, Operand(callee->name())); | 3152 __ li(a2, Operand(callee->name())); |
| 3153 __ Push(context_register(), a2); | 3153 __ Push(context_register(), a2); |
| 3154 __ CallRuntime(Runtime::kLoadLookupSlot, 2); | 3154 __ CallRuntime(Runtime::kLoadLookupSlot, 2); |
| 3155 __ Push(v0, v1); // Function, receiver. | 3155 __ Push(v0, v1); // Function, receiver. |
| 3156 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); | 3156 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3189 Comment cmnt(masm_, "[ Call"); | 3189 Comment cmnt(masm_, "[ Call"); |
| 3190 Expression* callee = expr->expression(); | 3190 Expression* callee = expr->expression(); |
| 3191 Call::CallType call_type = expr->GetCallType(isolate()); | 3191 Call::CallType call_type = expr->GetCallType(isolate()); |
| 3192 | 3192 |
| 3193 if (call_type == Call::POSSIBLY_EVAL_CALL) { | 3193 if (call_type == Call::POSSIBLY_EVAL_CALL) { |
| 3194 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval | 3194 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval |
| 3195 // to resolve the function we need to call. Then we call the resolved | 3195 // to resolve the function we need to call. Then we call the resolved |
| 3196 // function using the given arguments. | 3196 // function using the given arguments. |
| 3197 ZoneList<Expression*>* args = expr->arguments(); | 3197 ZoneList<Expression*>* args = expr->arguments(); |
| 3198 int arg_count = args->length(); | 3198 int arg_count = args->length(); |
| 3199 | |
| 3200 { PreservePositionScope pos_scope(masm()->positions_recorder()); | |
| 3201 PushCalleeAndWithBaseObject(expr); | 3199 PushCalleeAndWithBaseObject(expr); |
| 3202 | 3200 |
| 3203 // Push the arguments. | 3201 // Push the arguments. |
| 3204 for (int i = 0; i < arg_count; i++) { | 3202 for (int i = 0; i < arg_count; i++) { |
| 3205 VisitForStackValue(args->at(i)); | 3203 VisitForStackValue(args->at(i)); |
| 3206 } | 3204 } |
| 3207 | 3205 |
| 3208 // Push a copy of the function (found below the arguments) and | 3206 // Push a copy of the function (found below the arguments) and |
| 3209 // resolve eval. | 3207 // resolve eval. |
| 3210 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 3208 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 3211 __ push(a1); | 3209 __ push(a1); |
| 3212 EmitResolvePossiblyDirectEval(arg_count); | 3210 EmitResolvePossiblyDirectEval(arg_count); |
| 3213 | 3211 |
| 3214 // Touch up the stack with the resolved function. | 3212 // Touch up the stack with the resolved function. |
| 3215 __ sd(v0, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 3213 __ sd(v0, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 3216 | 3214 |
| 3217 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); | 3215 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); |
| 3218 } | |
| 3219 // Record source position for debugger. | 3216 // Record source position for debugger. |
| 3220 SetSourcePosition(expr->position()); | 3217 SetExpressionPosition(expr); |
| 3221 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | 3218 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
| 3222 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 3219 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 3223 __ CallStub(&stub); | 3220 __ CallStub(&stub); |
| 3224 RecordJSReturnSite(expr); | 3221 RecordJSReturnSite(expr); |
| 3225 // Restore context register. | 3222 // Restore context register. |
| 3226 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3223 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 3227 context()->DropAndPlug(1, v0); | 3224 context()->DropAndPlug(1, v0); |
| 3228 } else if (call_type == Call::GLOBAL_CALL) { | 3225 } else if (call_type == Call::GLOBAL_CALL) { |
| 3229 EmitCallWithLoadIC(expr); | 3226 EmitCallWithLoadIC(expr); |
| 3230 } else if (call_type == Call::LOOKUP_SLOT_CALL) { | 3227 } else if (call_type == Call::LOOKUP_SLOT_CALL) { |
| 3231 // Call to a lookup slot (dynamically introduced variable). | 3228 // Call to a lookup slot (dynamically introduced variable). |
| 3232 PushCalleeAndWithBaseObject(expr); | 3229 PushCalleeAndWithBaseObject(expr); |
| 3233 EmitCall(expr); | 3230 EmitCall(expr); |
| 3234 } else if (call_type == Call::PROPERTY_CALL) { | 3231 } else if (call_type == Call::PROPERTY_CALL) { |
| 3235 Property* property = callee->AsProperty(); | 3232 Property* property = callee->AsProperty(); |
| 3236 bool is_named_call = property->key()->IsPropertyName(); | 3233 bool is_named_call = property->key()->IsPropertyName(); |
| 3237 if (property->IsSuperAccess()) { | 3234 if (property->IsSuperAccess()) { |
| 3238 if (is_named_call) { | 3235 if (is_named_call) { |
| 3239 EmitSuperCallWithLoadIC(expr); | 3236 EmitSuperCallWithLoadIC(expr); |
| 3240 } else { | 3237 } else { |
| 3241 EmitKeyedSuperCallWithLoadIC(expr); | 3238 EmitKeyedSuperCallWithLoadIC(expr); |
| 3242 } | 3239 } |
| 3243 } else { | 3240 } else { |
| 3244 { | |
| 3245 PreservePositionScope scope(masm()->positions_recorder()); | |
| 3246 VisitForStackValue(property->obj()); | 3241 VisitForStackValue(property->obj()); |
| 3247 } | |
| 3248 if (is_named_call) { | 3242 if (is_named_call) { |
| 3249 EmitCallWithLoadIC(expr); | 3243 EmitCallWithLoadIC(expr); |
| 3250 } else { | 3244 } else { |
| 3251 EmitKeyedCallWithLoadIC(expr, property->key()); | 3245 EmitKeyedCallWithLoadIC(expr, property->key()); |
| 3252 } | 3246 } |
| 3253 } | 3247 } |
| 3254 } else if (call_type == Call::SUPER_CALL) { | 3248 } else if (call_type == Call::SUPER_CALL) { |
| 3255 EmitSuperConstructorCall(expr); | 3249 EmitSuperConstructorCall(expr); |
| 3256 } else { | 3250 } else { |
| 3257 DCHECK(call_type == Call::OTHER_CALL); | 3251 DCHECK(call_type == Call::OTHER_CALL); |
| 3258 // Call to an arbitrary expression not handled specially above. | 3252 // Call to an arbitrary expression not handled specially above. |
| 3259 { PreservePositionScope scope(masm()->positions_recorder()); | |
| 3260 VisitForStackValue(callee); | 3253 VisitForStackValue(callee); |
| 3261 } | |
| 3262 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex); | 3254 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex); |
| 3263 __ push(a1); | 3255 __ push(a1); |
| 3264 // Emit function call. | 3256 // Emit function call. |
| 3265 EmitCall(expr); | 3257 EmitCall(expr); |
| 3266 } | 3258 } |
| 3267 | 3259 |
| 3268 #ifdef DEBUG | 3260 #ifdef DEBUG |
| 3269 // RecordJSReturnSite should have been called. | 3261 // RecordJSReturnSite should have been called. |
| 3270 DCHECK(expr->return_is_recorded_); | 3262 DCHECK(expr->return_is_recorded_); |
| 3271 #endif | 3263 #endif |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3286 | 3278 |
| 3287 // Push the arguments ("left-to-right") on the stack. | 3279 // Push the arguments ("left-to-right") on the stack. |
| 3288 ZoneList<Expression*>* args = expr->arguments(); | 3280 ZoneList<Expression*>* args = expr->arguments(); |
| 3289 int arg_count = args->length(); | 3281 int arg_count = args->length(); |
| 3290 for (int i = 0; i < arg_count; i++) { | 3282 for (int i = 0; i < arg_count; i++) { |
| 3291 VisitForStackValue(args->at(i)); | 3283 VisitForStackValue(args->at(i)); |
| 3292 } | 3284 } |
| 3293 | 3285 |
| 3294 // Call the construct call builtin that handles allocation and | 3286 // Call the construct call builtin that handles allocation and |
| 3295 // constructor invocation. | 3287 // constructor invocation. |
| 3296 SetSourcePosition(expr->position()); | 3288 SetExpressionPosition(expr); |
| 3297 | 3289 |
| 3298 // Load function and argument count into a1 and a0. | 3290 // Load function and argument count into a1 and a0. |
| 3299 __ li(a0, Operand(arg_count)); | 3291 __ li(a0, Operand(arg_count)); |
| 3300 __ ld(a1, MemOperand(sp, arg_count * kPointerSize)); | 3292 __ ld(a1, MemOperand(sp, arg_count * kPointerSize)); |
| 3301 | 3293 |
| 3302 // Record call targets in unoptimized code. | 3294 // Record call targets in unoptimized code. |
| 3303 if (FLAG_pretenuring_call_new) { | 3295 if (FLAG_pretenuring_call_new) { |
| 3304 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); | 3296 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); |
| 3305 DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() == | 3297 DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() == |
| 3306 expr->CallNewFeedbackSlot().ToInt() + 1); | 3298 expr->CallNewFeedbackSlot().ToInt() + 1); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 3329 | 3321 |
| 3330 // Push the arguments ("left-to-right") on the stack. | 3322 // Push the arguments ("left-to-right") on the stack. |
| 3331 ZoneList<Expression*>* args = expr->arguments(); | 3323 ZoneList<Expression*>* args = expr->arguments(); |
| 3332 int arg_count = args->length(); | 3324 int arg_count = args->length(); |
| 3333 for (int i = 0; i < arg_count; i++) { | 3325 for (int i = 0; i < arg_count; i++) { |
| 3334 VisitForStackValue(args->at(i)); | 3326 VisitForStackValue(args->at(i)); |
| 3335 } | 3327 } |
| 3336 | 3328 |
| 3337 // Call the construct call builtin that handles allocation and | 3329 // Call the construct call builtin that handles allocation and |
| 3338 // constructor invocation. | 3330 // constructor invocation. |
| 3339 SetSourcePosition(expr->position()); | 3331 SetExpressionPosition(expr); |
| 3340 | 3332 |
| 3341 // Load function and argument count into a1 and a0. | 3333 // Load function and argument count into a1 and a0. |
| 3342 __ li(a0, Operand(arg_count)); | 3334 __ li(a0, Operand(arg_count)); |
| 3343 __ ld(a1, MemOperand(sp, arg_count * kPointerSize)); | 3335 __ ld(a1, MemOperand(sp, arg_count * kPointerSize)); |
| 3344 | 3336 |
| 3345 // Record call targets in unoptimized code. | 3337 // Record call targets in unoptimized code. |
| 3346 if (FLAG_pretenuring_call_new) { | 3338 if (FLAG_pretenuring_call_new) { |
| 3347 UNREACHABLE(); | 3339 UNREACHABLE(); |
| 3348 /* TODO(dslomov): support pretenuring. | 3340 /* TODO(dslomov): support pretenuring. |
| 3349 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); | 3341 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); |
| (...skipping 1395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4745 __ li(LoadDescriptor::SlotRegister(), | 4737 __ li(LoadDescriptor::SlotRegister(), |
| 4746 Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot()))); | 4738 Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot()))); |
| 4747 CallLoadIC(NOT_CONTEXTUAL); | 4739 CallLoadIC(NOT_CONTEXTUAL); |
| 4748 } | 4740 } |
| 4749 | 4741 |
| 4750 | 4742 |
| 4751 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 4743 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
| 4752 ZoneList<Expression*>* args = expr->arguments(); | 4744 ZoneList<Expression*>* args = expr->arguments(); |
| 4753 int arg_count = args->length(); | 4745 int arg_count = args->length(); |
| 4754 | 4746 |
| 4755 // Record source position of the IC call. | 4747 SetExpressionPosition(expr); |
| 4756 SetSourcePosition(expr->position()); | |
| 4757 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | 4748 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
| 4758 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 4749 __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
| 4759 __ CallStub(&stub); | 4750 __ CallStub(&stub); |
| 4760 } | 4751 } |
| 4761 | 4752 |
| 4762 | 4753 |
| 4763 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 4754 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
| 4764 ZoneList<Expression*>* args = expr->arguments(); | 4755 ZoneList<Expression*>* args = expr->arguments(); |
| 4765 int arg_count = args->length(); | 4756 int arg_count = args->length(); |
| 4766 | 4757 |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4923 default: | 4914 default: |
| 4924 UNREACHABLE(); | 4915 UNREACHABLE(); |
| 4925 } | 4916 } |
| 4926 } | 4917 } |
| 4927 | 4918 |
| 4928 | 4919 |
| 4929 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4920 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
| 4930 DCHECK(expr->expression()->IsValidReferenceExpression()); | 4921 DCHECK(expr->expression()->IsValidReferenceExpression()); |
| 4931 | 4922 |
| 4932 Comment cmnt(masm_, "[ CountOperation"); | 4923 Comment cmnt(masm_, "[ CountOperation"); |
| 4933 SetSourcePosition(expr->position()); | |
| 4934 | 4924 |
| 4935 Property* prop = expr->expression()->AsProperty(); | 4925 Property* prop = expr->expression()->AsProperty(); |
| 4936 LhsKind assign_type = Property::GetAssignType(prop); | 4926 LhsKind assign_type = Property::GetAssignType(prop); |
| 4937 | 4927 |
| 4938 // Evaluate expression and get value. | 4928 // Evaluate expression and get value. |
| 4939 if (assign_type == VARIABLE) { | 4929 if (assign_type == VARIABLE) { |
| 4940 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4930 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
| 4941 AccumulatorValueContext context(this); | 4931 AccumulatorValueContext context(this); |
| 4942 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4932 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
| 4943 } else { | 4933 } else { |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5080 __ sd(v0, MemOperand(sp, 3 * kPointerSize)); | 5070 __ sd(v0, MemOperand(sp, 3 * kPointerSize)); |
| 5081 break; | 5071 break; |
| 5082 } | 5072 } |
| 5083 } | 5073 } |
| 5084 } | 5074 } |
| 5085 | 5075 |
| 5086 __ bind(&stub_call); | 5076 __ bind(&stub_call); |
| 5087 __ mov(a1, v0); | 5077 __ mov(a1, v0); |
| 5088 __ li(a0, Operand(Smi::FromInt(count_value))); | 5078 __ li(a0, Operand(Smi::FromInt(count_value))); |
| 5089 | 5079 |
| 5090 // Record position before stub call. | 5080 SetExpressionPosition(expr); |
| 5091 SetSourcePosition(expr->position()); | 5081 |
| 5092 | 5082 |
| 5093 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD, | 5083 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD, |
| 5094 strength(language_mode())).code(); | 5084 strength(language_mode())).code(); |
| 5095 CallIC(code, expr->CountBinOpFeedbackId()); | 5085 CallIC(code, expr->CountBinOpFeedbackId()); |
| 5096 patch_site.EmitPatchInfo(); | 5086 patch_site.EmitPatchInfo(); |
| 5097 __ bind(&done); | 5087 __ bind(&done); |
| 5098 | 5088 |
| 5099 if (is_strong(language_mode())) { | 5089 if (is_strong(language_mode())) { |
| 5100 PrepareForBailoutForId(expr->ToNumberId(), TOS_REG); | 5090 PrepareForBailoutForId(expr->ToNumberId(), TOS_REG); |
| 5101 } | 5091 } |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5297 Split(eq, a1, Operand(zero_reg), if_true, if_false, fall_through); | 5287 Split(eq, a1, Operand(zero_reg), if_true, if_false, fall_through); |
| 5298 } else { | 5288 } else { |
| 5299 if (if_false != fall_through) __ jmp(if_false); | 5289 if (if_false != fall_through) __ jmp(if_false); |
| 5300 } | 5290 } |
| 5301 context()->Plug(if_true, if_false); | 5291 context()->Plug(if_true, if_false); |
| 5302 } | 5292 } |
| 5303 | 5293 |
| 5304 | 5294 |
| 5305 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { | 5295 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { |
| 5306 Comment cmnt(masm_, "[ CompareOperation"); | 5296 Comment cmnt(masm_, "[ CompareOperation"); |
| 5307 SetSourcePosition(expr->position()); | 5297 SetExpressionPosition(expr); |
| 5308 | 5298 |
| 5309 // First we try a fast inlined version of the compare when one of | 5299 // First we try a fast inlined version of the compare when one of |
| 5310 // the operands is a literal. | 5300 // the operands is a literal. |
| 5311 if (TryLiteralCompare(expr)) return; | 5301 if (TryLiteralCompare(expr)) return; |
| 5312 | 5302 |
| 5313 // Always perform the comparison for its control flow. Pack the result | 5303 // Always perform the comparison for its control flow. Pack the result |
| 5314 // into the expression's context after the comparison is performed. | 5304 // into the expression's context after the comparison is performed. |
| 5315 Label materialize_true, materialize_false; | 5305 Label materialize_true, materialize_false; |
| 5316 Label* if_true = NULL; | 5306 Label* if_true = NULL; |
| 5317 Label* if_false = NULL; | 5307 Label* if_false = NULL; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 5348 | 5338 |
| 5349 bool inline_smi_code = ShouldInlineSmiCase(op); | 5339 bool inline_smi_code = ShouldInlineSmiCase(op); |
| 5350 JumpPatchSite patch_site(masm_); | 5340 JumpPatchSite patch_site(masm_); |
| 5351 if (inline_smi_code) { | 5341 if (inline_smi_code) { |
| 5352 Label slow_case; | 5342 Label slow_case; |
| 5353 __ Or(a2, a0, Operand(a1)); | 5343 __ Or(a2, a0, Operand(a1)); |
| 5354 patch_site.EmitJumpIfNotSmi(a2, &slow_case); | 5344 patch_site.EmitJumpIfNotSmi(a2, &slow_case); |
| 5355 Split(cc, a1, Operand(a0), if_true, if_false, NULL); | 5345 Split(cc, a1, Operand(a0), if_true, if_false, NULL); |
| 5356 __ bind(&slow_case); | 5346 __ bind(&slow_case); |
| 5357 } | 5347 } |
| 5358 // Record position and call the compare IC. | 5348 |
| 5359 SetSourcePosition(expr->position()); | |
| 5360 Handle<Code> ic = CodeFactory::CompareIC( | 5349 Handle<Code> ic = CodeFactory::CompareIC( |
| 5361 isolate(), op, strength(language_mode())).code(); | 5350 isolate(), op, strength(language_mode())).code(); |
| 5362 CallIC(ic, expr->CompareOperationFeedbackId()); | 5351 CallIC(ic, expr->CompareOperationFeedbackId()); |
| 5363 patch_site.EmitPatchInfo(); | 5352 patch_site.EmitPatchInfo(); |
| 5364 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 5353 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 5365 Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through); | 5354 Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through); |
| 5366 } | 5355 } |
| 5367 } | 5356 } |
| 5368 | 5357 |
| 5369 // Convert the result of the comparison into one expected for this | 5358 // Convert the result of the comparison into one expected for this |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5594 reinterpret_cast<uint64_t>( | 5583 reinterpret_cast<uint64_t>( |
| 5595 isolate->builtins()->OsrAfterStackCheck()->entry())); | 5584 isolate->builtins()->OsrAfterStackCheck()->entry())); |
| 5596 return OSR_AFTER_STACK_CHECK; | 5585 return OSR_AFTER_STACK_CHECK; |
| 5597 } | 5586 } |
| 5598 | 5587 |
| 5599 | 5588 |
| 5600 } // namespace internal | 5589 } // namespace internal |
| 5601 } // namespace v8 | 5590 } // namespace v8 |
| 5602 | 5591 |
| 5603 #endif // V8_TARGET_ARCH_MIPS64 | 5592 #endif // V8_TARGET_ARCH_MIPS64 |
| OLD | NEW |