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 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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. |
2815 Property* prop = expr->target()->AsProperty(); | 2817 Property* prop = expr->target()->AsProperty(); |
2816 DCHECK(prop != NULL); | 2818 DCHECK(prop != NULL); |
2817 DCHECK(prop->key()->IsLiteral()); | 2819 DCHECK(prop->key()->IsLiteral()); |
2818 | 2820 |
2819 // Record source code position before IC call. | |
2820 SetSourcePosition(expr->position()); | |
2821 __ mov(StoreDescriptor::ValueRegister(), result_register()); | 2821 __ mov(StoreDescriptor::ValueRegister(), result_register()); |
2822 __ li(StoreDescriptor::NameRegister(), | 2822 __ li(StoreDescriptor::NameRegister(), |
2823 Operand(prop->key()->AsLiteral()->value())); | 2823 Operand(prop->key()->AsLiteral()->value())); |
2824 __ pop(StoreDescriptor::ReceiverRegister()); | 2824 __ pop(StoreDescriptor::ReceiverRegister()); |
2825 if (FLAG_vector_stores) { | 2825 if (FLAG_vector_stores) { |
2826 EmitLoadStoreICSlot(expr->AssignmentSlot()); | 2826 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
2827 CallStoreIC(); | 2827 CallStoreIC(); |
2828 } else { | 2828 } else { |
2829 CallStoreIC(expr->AssignmentFeedbackId()); | 2829 CallStoreIC(expr->AssignmentFeedbackId()); |
2830 } | 2830 } |
(...skipping 28 matching lines...) Expand all Loading... |
2859 __ Push(v0); | 2859 __ Push(v0); |
2860 __ CallRuntime( | 2860 __ CallRuntime( |
2861 (is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict | 2861 (is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
2862 : Runtime::kStoreKeyedToSuper_Sloppy), | 2862 : Runtime::kStoreKeyedToSuper_Sloppy), |
2863 4); | 2863 4); |
2864 } | 2864 } |
2865 | 2865 |
2866 | 2866 |
2867 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2867 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2868 // Assignment to a property, using a keyed store IC. | 2868 // Assignment to a property, using a keyed store IC. |
2869 | |
2870 // Record source code position before IC call. | |
2871 SetSourcePosition(expr->position()); | |
2872 // Call keyed store IC. | 2869 // Call keyed store IC. |
2873 // The arguments are: | 2870 // The arguments are: |
2874 // - a0 is the value, | 2871 // - a0 is the value, |
2875 // - a1 is the key, | 2872 // - a1 is the key, |
2876 // - a2 is the receiver. | 2873 // - a2 is the receiver. |
2877 __ mov(StoreDescriptor::ValueRegister(), result_register()); | 2874 __ mov(StoreDescriptor::ValueRegister(), result_register()); |
2878 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); | 2875 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); |
2879 DCHECK(StoreDescriptor::ValueRegister().is(a0)); | 2876 DCHECK(StoreDescriptor::ValueRegister().is(a0)); |
2880 | 2877 |
2881 Handle<Code> ic = | 2878 Handle<Code> ic = |
2882 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2879 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
2883 if (FLAG_vector_stores) { | 2880 if (FLAG_vector_stores) { |
2884 EmitLoadStoreICSlot(expr->AssignmentSlot()); | 2881 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
2885 CallIC(ic); | 2882 CallIC(ic); |
2886 } else { | 2883 } else { |
2887 CallIC(ic, expr->AssignmentFeedbackId()); | 2884 CallIC(ic, expr->AssignmentFeedbackId()); |
2888 } | 2885 } |
2889 | 2886 |
2890 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2887 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2891 context()->Plug(v0); | 2888 context()->Plug(v0); |
2892 } | 2889 } |
2893 | 2890 |
2894 | 2891 |
2895 void FullCodeGenerator::VisitProperty(Property* expr) { | 2892 void FullCodeGenerator::VisitProperty(Property* expr) { |
2896 Comment cmnt(masm_, "[ Property"); | 2893 Comment cmnt(masm_, "[ Property"); |
| 2894 SetExpressionPosition(expr); |
| 2895 |
2897 Expression* key = expr->key(); | 2896 Expression* key = expr->key(); |
2898 | 2897 |
2899 if (key->IsPropertyName()) { | 2898 if (key->IsPropertyName()) { |
2900 if (!expr->IsSuperAccess()) { | 2899 if (!expr->IsSuperAccess()) { |
2901 VisitForAccumulatorValue(expr->obj()); | 2900 VisitForAccumulatorValue(expr->obj()); |
2902 __ Move(LoadDescriptor::ReceiverRegister(), v0); | 2901 __ Move(LoadDescriptor::ReceiverRegister(), v0); |
2903 EmitNamedPropertyLoad(expr); | 2902 EmitNamedPropertyLoad(expr); |
2904 } else { | 2903 } else { |
2905 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); | 2904 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); |
2906 VisitForStackValue( | 2905 VisitForStackValue( |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2962 __ lw(at, MemOperand(sp, 0)); | 2961 __ lw(at, MemOperand(sp, 0)); |
2963 __ push(at); | 2962 __ push(at); |
2964 __ sw(v0, MemOperand(sp, kPointerSize)); | 2963 __ sw(v0, MemOperand(sp, kPointerSize)); |
2965 } | 2964 } |
2966 | 2965 |
2967 EmitCall(expr, call_type); | 2966 EmitCall(expr, call_type); |
2968 } | 2967 } |
2969 | 2968 |
2970 | 2969 |
2971 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | 2970 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { |
| 2971 SetExpressionPosition(expr); |
2972 Expression* callee = expr->expression(); | 2972 Expression* callee = expr->expression(); |
2973 DCHECK(callee->IsProperty()); | 2973 DCHECK(callee->IsProperty()); |
2974 Property* prop = callee->AsProperty(); | 2974 Property* prop = callee->AsProperty(); |
2975 DCHECK(prop->IsSuperAccess()); | 2975 DCHECK(prop->IsSuperAccess()); |
2976 | 2976 |
2977 SetSourcePosition(prop->position()); | |
2978 Literal* key = prop->key()->AsLiteral(); | 2977 Literal* key = prop->key()->AsLiteral(); |
2979 DCHECK(!key->value()->IsSmi()); | 2978 DCHECK(!key->value()->IsSmi()); |
2980 // Load the function from the receiver. | 2979 // Load the function from the receiver. |
2981 const Register scratch = a1; | 2980 const Register scratch = a1; |
2982 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | 2981 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); |
2983 VisitForAccumulatorValue(super_ref->home_object()); | 2982 VisitForAccumulatorValue(super_ref->home_object()); |
2984 __ mov(scratch, v0); | 2983 __ mov(scratch, v0); |
2985 VisitForAccumulatorValue(super_ref->this_var()); | 2984 VisitForAccumulatorValue(super_ref->this_var()); |
2986 __ Push(scratch, v0, v0, scratch); | 2985 __ Push(scratch, v0, v0, scratch); |
2987 __ Push(key->value()); | 2986 __ Push(key->value()); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3029 EmitCall(expr, CallICState::METHOD); | 3028 EmitCall(expr, CallICState::METHOD); |
3030 } | 3029 } |
3031 | 3030 |
3032 | 3031 |
3033 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | 3032 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { |
3034 Expression* callee = expr->expression(); | 3033 Expression* callee = expr->expression(); |
3035 DCHECK(callee->IsProperty()); | 3034 DCHECK(callee->IsProperty()); |
3036 Property* prop = callee->AsProperty(); | 3035 Property* prop = callee->AsProperty(); |
3037 DCHECK(prop->IsSuperAccess()); | 3036 DCHECK(prop->IsSuperAccess()); |
3038 | 3037 |
3039 SetSourcePosition(prop->position()); | 3038 SetExpressionPosition(prop); |
3040 // Load the function from the receiver. | 3039 // Load the function from the receiver. |
3041 const Register scratch = a1; | 3040 const Register scratch = a1; |
3042 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | 3041 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); |
3043 VisitForAccumulatorValue(super_ref->home_object()); | 3042 VisitForAccumulatorValue(super_ref->home_object()); |
3044 __ Move(scratch, v0); | 3043 __ Move(scratch, v0); |
3045 VisitForAccumulatorValue(super_ref->this_var()); | 3044 VisitForAccumulatorValue(super_ref->this_var()); |
3046 __ Push(scratch, v0, v0, scratch); | 3045 __ Push(scratch, v0, v0, scratch); |
3047 VisitForStackValue(prop->key()); | 3046 VisitForStackValue(prop->key()); |
3048 __ Push(Smi::FromInt(language_mode())); | 3047 __ Push(Smi::FromInt(language_mode())); |
3049 | 3048 |
(...skipping 13 matching lines...) Expand all Loading... |
3063 // - target function | 3062 // - target function |
3064 // - this (receiver) | 3063 // - this (receiver) |
3065 EmitCall(expr, CallICState::METHOD); | 3064 EmitCall(expr, CallICState::METHOD); |
3066 } | 3065 } |
3067 | 3066 |
3068 | 3067 |
3069 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) { | 3068 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) { |
3070 // Load the arguments. | 3069 // Load the arguments. |
3071 ZoneList<Expression*>* args = expr->arguments(); | 3070 ZoneList<Expression*>* args = expr->arguments(); |
3072 int arg_count = args->length(); | 3071 int arg_count = args->length(); |
3073 { PreservePositionScope scope(masm()->positions_recorder()); | 3072 for (int i = 0; i < arg_count; i++) { |
3074 for (int i = 0; i < arg_count; i++) { | 3073 VisitForStackValue(args->at(i)); |
3075 VisitForStackValue(args->at(i)); | |
3076 } | |
3077 } | 3074 } |
3078 | 3075 |
3079 // Record source position of the IC call. | 3076 // Record source position of the IC call. |
3080 SetSourcePosition(expr->position()); | 3077 SetExpressionPosition(expr); |
3081 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code(); | 3078 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code(); |
3082 __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackICSlot()))); | 3079 __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackICSlot()))); |
3083 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 3080 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
3084 // Don't assign a type feedback id to the IC, since type feedback is provided | 3081 // Don't assign a type feedback id to the IC, since type feedback is provided |
3085 // by the vector above. | 3082 // by the vector above. |
3086 CallIC(ic); | 3083 CallIC(ic); |
3087 | 3084 |
3088 RecordJSReturnSite(expr); | 3085 RecordJSReturnSite(expr); |
3089 // Restore context register. | 3086 // Restore context register. |
3090 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3087 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3129 | 3126 |
3130 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); | 3127 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); |
3131 } | 3128 } |
3132 | 3129 |
3133 | 3130 |
3134 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. | 3131 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. |
3135 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { | 3132 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { |
3136 VariableProxy* callee = expr->expression()->AsVariableProxy(); | 3133 VariableProxy* callee = expr->expression()->AsVariableProxy(); |
3137 if (callee->var()->IsLookupSlot()) { | 3134 if (callee->var()->IsLookupSlot()) { |
3138 Label slow, done; | 3135 Label slow, done; |
3139 SetSourcePosition(callee->position()); | 3136 |
3140 { | 3137 SetExpressionPosition(callee); |
3141 PreservePositionScope scope(masm()->positions_recorder()); | 3138 // Generate code for loading from variables potentially shadowed by |
3142 // Generate code for loading from variables potentially shadowed | 3139 // eval-introduced variables. |
3143 // by eval-introduced variables. | 3140 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); |
3144 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); | |
3145 } | |
3146 | 3141 |
3147 __ bind(&slow); | 3142 __ bind(&slow); |
3148 // Call the runtime to find the function to call (returned in v0) | 3143 // Call the runtime to find the function to call (returned in v0) |
3149 // and the object holding it (returned in v1). | 3144 // and the object holding it (returned in v1). |
3150 DCHECK(!context_register().is(a2)); | 3145 DCHECK(!context_register().is(a2)); |
3151 __ li(a2, Operand(callee->name())); | 3146 __ li(a2, Operand(callee->name())); |
3152 __ Push(context_register(), a2); | 3147 __ Push(context_register(), a2); |
3153 __ CallRuntime(Runtime::kLoadLookupSlot, 2); | 3148 __ CallRuntime(Runtime::kLoadLookupSlot, 2); |
3154 __ Push(v0, v1); // Function, receiver. | 3149 __ Push(v0, v1); // Function, receiver. |
3155 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); | 3150 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3188 Comment cmnt(masm_, "[ Call"); | 3183 Comment cmnt(masm_, "[ Call"); |
3189 Expression* callee = expr->expression(); | 3184 Expression* callee = expr->expression(); |
3190 Call::CallType call_type = expr->GetCallType(isolate()); | 3185 Call::CallType call_type = expr->GetCallType(isolate()); |
3191 | 3186 |
3192 if (call_type == Call::POSSIBLY_EVAL_CALL) { | 3187 if (call_type == Call::POSSIBLY_EVAL_CALL) { |
3193 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval | 3188 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval |
3194 // to resolve the function we need to call. Then we call the resolved | 3189 // to resolve the function we need to call. Then we call the resolved |
3195 // function using the given arguments. | 3190 // function using the given arguments. |
3196 ZoneList<Expression*>* args = expr->arguments(); | 3191 ZoneList<Expression*>* args = expr->arguments(); |
3197 int arg_count = args->length(); | 3192 int arg_count = args->length(); |
3198 | |
3199 { PreservePositionScope pos_scope(masm()->positions_recorder()); | |
3200 PushCalleeAndWithBaseObject(expr); | 3193 PushCalleeAndWithBaseObject(expr); |
3201 | 3194 |
3202 // Push the arguments. | 3195 // Push the arguments. |
3203 for (int i = 0; i < arg_count; i++) { | 3196 for (int i = 0; i < arg_count; i++) { |
3204 VisitForStackValue(args->at(i)); | 3197 VisitForStackValue(args->at(i)); |
3205 } | 3198 } |
3206 | 3199 |
3207 // Push a copy of the function (found below the arguments) and | 3200 // Push a copy of the function (found below the arguments) and |
3208 // resolve eval. | 3201 // resolve eval. |
3209 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 3202 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
3210 __ push(a1); | 3203 __ push(a1); |
3211 EmitResolvePossiblyDirectEval(arg_count); | 3204 EmitResolvePossiblyDirectEval(arg_count); |
3212 | 3205 |
3213 // Touch up the stack with the resolved function. | 3206 // Touch up the stack with the resolved function. |
3214 __ sw(v0, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 3207 __ sw(v0, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
3215 | 3208 |
3216 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); | 3209 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); |
3217 } | |
3218 // Record source position for debugger. | 3210 // Record source position for debugger. |
3219 SetSourcePosition(expr->position()); | 3211 SetExpressionPosition(expr); |
3220 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | 3212 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
3221 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 3213 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
3222 __ CallStub(&stub); | 3214 __ CallStub(&stub); |
3223 RecordJSReturnSite(expr); | 3215 RecordJSReturnSite(expr); |
3224 // Restore context register. | 3216 // Restore context register. |
3225 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3217 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3226 context()->DropAndPlug(1, v0); | 3218 context()->DropAndPlug(1, v0); |
3227 } else if (call_type == Call::GLOBAL_CALL) { | 3219 } else if (call_type == Call::GLOBAL_CALL) { |
3228 EmitCallWithLoadIC(expr); | 3220 EmitCallWithLoadIC(expr); |
3229 } else if (call_type == Call::LOOKUP_SLOT_CALL) { | 3221 } else if (call_type == Call::LOOKUP_SLOT_CALL) { |
3230 // Call to a lookup slot (dynamically introduced variable). | 3222 // Call to a lookup slot (dynamically introduced variable). |
3231 PushCalleeAndWithBaseObject(expr); | 3223 PushCalleeAndWithBaseObject(expr); |
3232 EmitCall(expr); | 3224 EmitCall(expr); |
3233 } else if (call_type == Call::PROPERTY_CALL) { | 3225 } else if (call_type == Call::PROPERTY_CALL) { |
3234 Property* property = callee->AsProperty(); | 3226 Property* property = callee->AsProperty(); |
3235 bool is_named_call = property->key()->IsPropertyName(); | 3227 bool is_named_call = property->key()->IsPropertyName(); |
3236 if (property->IsSuperAccess()) { | 3228 if (property->IsSuperAccess()) { |
3237 if (is_named_call) { | 3229 if (is_named_call) { |
3238 EmitSuperCallWithLoadIC(expr); | 3230 EmitSuperCallWithLoadIC(expr); |
3239 } else { | 3231 } else { |
3240 EmitKeyedSuperCallWithLoadIC(expr); | 3232 EmitKeyedSuperCallWithLoadIC(expr); |
3241 } | 3233 } |
3242 } else { | 3234 } else { |
3243 { | |
3244 PreservePositionScope scope(masm()->positions_recorder()); | |
3245 VisitForStackValue(property->obj()); | 3235 VisitForStackValue(property->obj()); |
3246 } | |
3247 if (is_named_call) { | 3236 if (is_named_call) { |
3248 EmitCallWithLoadIC(expr); | 3237 EmitCallWithLoadIC(expr); |
3249 } else { | 3238 } else { |
3250 EmitKeyedCallWithLoadIC(expr, property->key()); | 3239 EmitKeyedCallWithLoadIC(expr, property->key()); |
3251 } | 3240 } |
3252 } | 3241 } |
3253 } else if (call_type == Call::SUPER_CALL) { | 3242 } else if (call_type == Call::SUPER_CALL) { |
3254 EmitSuperConstructorCall(expr); | 3243 EmitSuperConstructorCall(expr); |
3255 } else { | 3244 } else { |
3256 DCHECK(call_type == Call::OTHER_CALL); | 3245 DCHECK(call_type == Call::OTHER_CALL); |
3257 // Call to an arbitrary expression not handled specially above. | 3246 // Call to an arbitrary expression not handled specially above. |
3258 { PreservePositionScope scope(masm()->positions_recorder()); | |
3259 VisitForStackValue(callee); | 3247 VisitForStackValue(callee); |
3260 } | |
3261 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex); | 3248 __ LoadRoot(a1, Heap::kUndefinedValueRootIndex); |
3262 __ push(a1); | 3249 __ push(a1); |
3263 // Emit function call. | 3250 // Emit function call. |
3264 EmitCall(expr); | 3251 EmitCall(expr); |
3265 } | 3252 } |
3266 | 3253 |
3267 #ifdef DEBUG | 3254 #ifdef DEBUG |
3268 // RecordJSReturnSite should have been called. | 3255 // RecordJSReturnSite should have been called. |
3269 DCHECK(expr->return_is_recorded_); | 3256 DCHECK(expr->return_is_recorded_); |
3270 #endif | 3257 #endif |
(...skipping 14 matching lines...) Expand all Loading... |
3285 | 3272 |
3286 // Push the arguments ("left-to-right") on the stack. | 3273 // Push the arguments ("left-to-right") on the stack. |
3287 ZoneList<Expression*>* args = expr->arguments(); | 3274 ZoneList<Expression*>* args = expr->arguments(); |
3288 int arg_count = args->length(); | 3275 int arg_count = args->length(); |
3289 for (int i = 0; i < arg_count; i++) { | 3276 for (int i = 0; i < arg_count; i++) { |
3290 VisitForStackValue(args->at(i)); | 3277 VisitForStackValue(args->at(i)); |
3291 } | 3278 } |
3292 | 3279 |
3293 // Call the construct call builtin that handles allocation and | 3280 // Call the construct call builtin that handles allocation and |
3294 // constructor invocation. | 3281 // constructor invocation. |
3295 SetSourcePosition(expr->position()); | 3282 SetExpressionPosition(expr); |
3296 | 3283 |
3297 // Load function and argument count into a1 and a0. | 3284 // Load function and argument count into a1 and a0. |
3298 __ li(a0, Operand(arg_count)); | 3285 __ li(a0, Operand(arg_count)); |
3299 __ lw(a1, MemOperand(sp, arg_count * kPointerSize)); | 3286 __ lw(a1, MemOperand(sp, arg_count * kPointerSize)); |
3300 | 3287 |
3301 // Record call targets in unoptimized code. | 3288 // Record call targets in unoptimized code. |
3302 if (FLAG_pretenuring_call_new) { | 3289 if (FLAG_pretenuring_call_new) { |
3303 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); | 3290 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); |
3304 DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() == | 3291 DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() == |
3305 expr->CallNewFeedbackSlot().ToInt() + 1); | 3292 expr->CallNewFeedbackSlot().ToInt() + 1); |
(...skipping 22 matching lines...) Expand all Loading... |
3328 | 3315 |
3329 // Push the arguments ("left-to-right") on the stack. | 3316 // Push the arguments ("left-to-right") on the stack. |
3330 ZoneList<Expression*>* args = expr->arguments(); | 3317 ZoneList<Expression*>* args = expr->arguments(); |
3331 int arg_count = args->length(); | 3318 int arg_count = args->length(); |
3332 for (int i = 0; i < arg_count; i++) { | 3319 for (int i = 0; i < arg_count; i++) { |
3333 VisitForStackValue(args->at(i)); | 3320 VisitForStackValue(args->at(i)); |
3334 } | 3321 } |
3335 | 3322 |
3336 // Call the construct call builtin that handles allocation and | 3323 // Call the construct call builtin that handles allocation and |
3337 // constructor invocation. | 3324 // constructor invocation. |
3338 SetSourcePosition(expr->position()); | 3325 SetExpressionPosition(expr); |
3339 | 3326 |
3340 // Load function and argument count into a1 and a0. | 3327 // Load function and argument count into a1 and a0. |
3341 __ li(a0, Operand(arg_count)); | 3328 __ li(a0, Operand(arg_count)); |
3342 __ lw(a1, MemOperand(sp, arg_count * kPointerSize)); | 3329 __ lw(a1, MemOperand(sp, arg_count * kPointerSize)); |
3343 | 3330 |
3344 // Record call targets in unoptimized code. | 3331 // Record call targets in unoptimized code. |
3345 if (FLAG_pretenuring_call_new) { | 3332 if (FLAG_pretenuring_call_new) { |
3346 UNREACHABLE(); | 3333 UNREACHABLE(); |
3347 /* TODO(dslomov): support pretenuring. | 3334 /* TODO(dslomov): support pretenuring. |
3348 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); | 3335 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); |
(...skipping 1393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4742 __ li(LoadDescriptor::SlotRegister(), | 4729 __ li(LoadDescriptor::SlotRegister(), |
4743 Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot()))); | 4730 Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot()))); |
4744 CallLoadIC(NOT_CONTEXTUAL); | 4731 CallLoadIC(NOT_CONTEXTUAL); |
4745 } | 4732 } |
4746 | 4733 |
4747 | 4734 |
4748 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 4735 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
4749 ZoneList<Expression*>* args = expr->arguments(); | 4736 ZoneList<Expression*>* args = expr->arguments(); |
4750 int arg_count = args->length(); | 4737 int arg_count = args->length(); |
4751 | 4738 |
4752 // Record source position of the IC call. | 4739 SetExpressionPosition(expr); |
4753 SetSourcePosition(expr->position()); | |
4754 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | 4740 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
4755 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 4741 __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
4756 __ CallStub(&stub); | 4742 __ CallStub(&stub); |
4757 } | 4743 } |
4758 | 4744 |
4759 | 4745 |
4760 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 4746 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
4761 ZoneList<Expression*>* args = expr->arguments(); | 4747 ZoneList<Expression*>* args = expr->arguments(); |
4762 int arg_count = args->length(); | 4748 int arg_count = args->length(); |
4763 | 4749 |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4921 default: | 4907 default: |
4922 UNREACHABLE(); | 4908 UNREACHABLE(); |
4923 } | 4909 } |
4924 } | 4910 } |
4925 | 4911 |
4926 | 4912 |
4927 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4913 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
4928 DCHECK(expr->expression()->IsValidReferenceExpression()); | 4914 DCHECK(expr->expression()->IsValidReferenceExpression()); |
4929 | 4915 |
4930 Comment cmnt(masm_, "[ CountOperation"); | 4916 Comment cmnt(masm_, "[ CountOperation"); |
4931 SetSourcePosition(expr->position()); | |
4932 | 4917 |
4933 Property* prop = expr->expression()->AsProperty(); | 4918 Property* prop = expr->expression()->AsProperty(); |
4934 LhsKind assign_type = Property::GetAssignType(prop); | 4919 LhsKind assign_type = Property::GetAssignType(prop); |
4935 | 4920 |
4936 // Evaluate expression and get value. | 4921 // Evaluate expression and get value. |
4937 if (assign_type == VARIABLE) { | 4922 if (assign_type == VARIABLE) { |
4938 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4923 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
4939 AccumulatorValueContext context(this); | 4924 AccumulatorValueContext context(this); |
4940 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4925 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
4941 } else { | 4926 } else { |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5078 __ sw(v0, MemOperand(sp, 3 * kPointerSize)); | 5063 __ sw(v0, MemOperand(sp, 3 * kPointerSize)); |
5079 break; | 5064 break; |
5080 } | 5065 } |
5081 } | 5066 } |
5082 } | 5067 } |
5083 | 5068 |
5084 __ bind(&stub_call); | 5069 __ bind(&stub_call); |
5085 __ mov(a1, v0); | 5070 __ mov(a1, v0); |
5086 __ li(a0, Operand(Smi::FromInt(count_value))); | 5071 __ li(a0, Operand(Smi::FromInt(count_value))); |
5087 | 5072 |
5088 // Record position before stub call. | 5073 SetExpressionPosition(expr); |
5089 SetSourcePosition(expr->position()); | 5074 |
5090 | 5075 |
5091 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD, | 5076 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD, |
5092 strength(language_mode())).code(); | 5077 strength(language_mode())).code(); |
5093 CallIC(code, expr->CountBinOpFeedbackId()); | 5078 CallIC(code, expr->CountBinOpFeedbackId()); |
5094 patch_site.EmitPatchInfo(); | 5079 patch_site.EmitPatchInfo(); |
5095 __ bind(&done); | 5080 __ bind(&done); |
5096 | 5081 |
5097 if (is_strong(language_mode())) { | 5082 if (is_strong(language_mode())) { |
5098 PrepareForBailoutForId(expr->ToNumberId(), TOS_REG); | 5083 PrepareForBailoutForId(expr->ToNumberId(), TOS_REG); |
5099 } | 5084 } |
(...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); | 5280 Split(eq, a1, Operand(zero_reg), if_true, if_false, fall_through); |
5296 } else { | 5281 } else { |
5297 if (if_false != fall_through) __ jmp(if_false); | 5282 if (if_false != fall_through) __ jmp(if_false); |
5298 } | 5283 } |
5299 context()->Plug(if_true, if_false); | 5284 context()->Plug(if_true, if_false); |
5300 } | 5285 } |
5301 | 5286 |
5302 | 5287 |
5303 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { | 5288 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { |
5304 Comment cmnt(masm_, "[ CompareOperation"); | 5289 Comment cmnt(masm_, "[ CompareOperation"); |
5305 SetSourcePosition(expr->position()); | 5290 SetExpressionPosition(expr); |
5306 | 5291 |
5307 // First we try a fast inlined version of the compare when one of | 5292 // First we try a fast inlined version of the compare when one of |
5308 // the operands is a literal. | 5293 // the operands is a literal. |
5309 if (TryLiteralCompare(expr)) return; | 5294 if (TryLiteralCompare(expr)) return; |
5310 | 5295 |
5311 // Always perform the comparison for its control flow. Pack the result | 5296 // Always perform the comparison for its control flow. Pack the result |
5312 // into the expression's context after the comparison is performed. | 5297 // into the expression's context after the comparison is performed. |
5313 Label materialize_true, materialize_false; | 5298 Label materialize_true, materialize_false; |
5314 Label* if_true = NULL; | 5299 Label* if_true = NULL; |
5315 Label* if_false = NULL; | 5300 Label* if_false = NULL; |
(...skipping 30 matching lines...) Expand all Loading... |
5346 | 5331 |
5347 bool inline_smi_code = ShouldInlineSmiCase(op); | 5332 bool inline_smi_code = ShouldInlineSmiCase(op); |
5348 JumpPatchSite patch_site(masm_); | 5333 JumpPatchSite patch_site(masm_); |
5349 if (inline_smi_code) { | 5334 if (inline_smi_code) { |
5350 Label slow_case; | 5335 Label slow_case; |
5351 __ Or(a2, a0, Operand(a1)); | 5336 __ Or(a2, a0, Operand(a1)); |
5352 patch_site.EmitJumpIfNotSmi(a2, &slow_case); | 5337 patch_site.EmitJumpIfNotSmi(a2, &slow_case); |
5353 Split(cc, a1, Operand(a0), if_true, if_false, NULL); | 5338 Split(cc, a1, Operand(a0), if_true, if_false, NULL); |
5354 __ bind(&slow_case); | 5339 __ bind(&slow_case); |
5355 } | 5340 } |
5356 // Record position and call the compare IC. | 5341 |
5357 SetSourcePosition(expr->position()); | |
5358 Handle<Code> ic = CodeFactory::CompareIC( | 5342 Handle<Code> ic = CodeFactory::CompareIC( |
5359 isolate(), op, strength(language_mode())).code(); | 5343 isolate(), op, strength(language_mode())).code(); |
5360 CallIC(ic, expr->CompareOperationFeedbackId()); | 5344 CallIC(ic, expr->CompareOperationFeedbackId()); |
5361 patch_site.EmitPatchInfo(); | 5345 patch_site.EmitPatchInfo(); |
5362 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 5346 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
5363 Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through); | 5347 Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through); |
5364 } | 5348 } |
5365 } | 5349 } |
5366 | 5350 |
5367 // Convert the result of the comparison into one expected for this | 5351 // 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>( | 5572 reinterpret_cast<uint32_t>( |
5589 isolate->builtins()->OsrAfterStackCheck()->entry())); | 5573 isolate->builtins()->OsrAfterStackCheck()->entry())); |
5590 return OSR_AFTER_STACK_CHECK; | 5574 return OSR_AFTER_STACK_CHECK; |
5591 } | 5575 } |
5592 | 5576 |
5593 | 5577 |
5594 } // namespace internal | 5578 } // namespace internal |
5595 } // namespace v8 | 5579 } // namespace v8 |
5596 | 5580 |
5597 #endif // V8_TARGET_ARCH_MIPS | 5581 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |