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