OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_PPC | 7 #if V8_TARGET_ARCH_PPC |
8 | 8 |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 // Add a label for checking the size of the code used for returning. | 495 // Add a label for checking the size of the code used for returning. |
496 Label check_exit_codesize; | 496 Label check_exit_codesize; |
497 __ bind(&check_exit_codesize); | 497 __ bind(&check_exit_codesize); |
498 #endif | 498 #endif |
499 // Make sure that the constant pool is not emitted inside of the return | 499 // Make sure that the constant pool is not emitted inside of the return |
500 // sequence. | 500 // sequence. |
501 { | 501 { |
502 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); | 502 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); |
503 int32_t arg_count = info_->scope()->num_parameters() + 1; | 503 int32_t arg_count = info_->scope()->num_parameters() + 1; |
504 int32_t sp_delta = arg_count * kPointerSize; | 504 int32_t sp_delta = arg_count * kPointerSize; |
505 CodeGenerator::RecordPositions(masm_, function()->end_position() - 1); | 505 SetReturnPosition(function()); |
506 __ RecordJSReturn(); | 506 __ RecordJSReturn(); |
507 int no_frame_start = __ LeaveFrame(StackFrame::JAVA_SCRIPT, sp_delta); | 507 int no_frame_start = __ LeaveFrame(StackFrame::JAVA_SCRIPT, sp_delta); |
508 #if V8_TARGET_ARCH_PPC64 | 508 #if V8_TARGET_ARCH_PPC64 |
509 // With 64bit we may need nop() instructions to ensure we have | 509 // With 64bit we may need nop() instructions to ensure we have |
510 // enough space to SetDebugBreakAtReturn() | 510 // enough space to SetDebugBreakAtReturn() |
511 if (is_int16(sp_delta)) { | 511 if (is_int16(sp_delta)) { |
512 if (!FLAG_enable_embedded_constant_pool) masm_->nop(); | 512 if (!FLAG_enable_embedded_constant_pool) masm_->nop(); |
513 masm_->nop(); | 513 masm_->nop(); |
514 } | 514 } |
515 #endif | 515 #endif |
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1046 patch_site.EmitJumpIfNotSmi(r5, &slow_case); | 1046 patch_site.EmitJumpIfNotSmi(r5, &slow_case); |
1047 | 1047 |
1048 __ cmp(r4, r3); | 1048 __ cmp(r4, r3); |
1049 __ bne(&next_test); | 1049 __ bne(&next_test); |
1050 __ Drop(1); // Switch value is no longer needed. | 1050 __ Drop(1); // Switch value is no longer needed. |
1051 __ b(clause->body_target()); | 1051 __ b(clause->body_target()); |
1052 __ bind(&slow_case); | 1052 __ bind(&slow_case); |
1053 } | 1053 } |
1054 | 1054 |
1055 // Record position before stub call for type feedback. | 1055 // Record position before stub call for type feedback. |
1056 SetSourcePosition(clause->position()); | 1056 SetExpressionPosition(clause); |
1057 Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT, | 1057 Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT, |
1058 strength(language_mode())).code(); | 1058 strength(language_mode())).code(); |
1059 CallIC(ic, clause->CompareId()); | 1059 CallIC(ic, clause->CompareId()); |
1060 patch_site.EmitPatchInfo(); | 1060 patch_site.EmitPatchInfo(); |
1061 | 1061 |
1062 Label skip; | 1062 Label skip; |
1063 __ b(&skip); | 1063 __ b(&skip); |
1064 PrepareForBailout(clause, TOS_REG); | 1064 PrepareForBailout(clause, TOS_REG); |
1065 __ LoadRoot(ip, Heap::kTrueValueRootIndex); | 1065 __ LoadRoot(ip, Heap::kTrueValueRootIndex); |
1066 __ cmp(r3, ip); | 1066 __ cmp(r3, ip); |
(...skipping 27 matching lines...) Expand all Loading... |
1094 VisitStatements(clause->statements()); | 1094 VisitStatements(clause->statements()); |
1095 } | 1095 } |
1096 | 1096 |
1097 __ bind(nested_statement.break_label()); | 1097 __ bind(nested_statement.break_label()); |
1098 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 1098 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
1099 } | 1099 } |
1100 | 1100 |
1101 | 1101 |
1102 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { | 1102 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
1103 Comment cmnt(masm_, "[ ForInStatement"); | 1103 Comment cmnt(masm_, "[ ForInStatement"); |
| 1104 SetStatementPosition(stmt, SKIP_BREAK); |
| 1105 |
1104 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); | 1106 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); |
1105 SetStatementPosition(stmt); | |
1106 | 1107 |
1107 Label loop, exit; | 1108 Label loop, exit; |
1108 ForIn loop_statement(this, stmt); | 1109 ForIn loop_statement(this, stmt); |
1109 increment_loop_depth(); | 1110 increment_loop_depth(); |
1110 | 1111 |
1111 // Get the object to enumerate over. If the object is null or undefined, skip | 1112 // Get the object to enumerate over. If the object is null or undefined, skip |
1112 // over the loop. See ECMA-262 version 5, section 12.6.4. | 1113 // over the loop. See ECMA-262 version 5, section 12.6.4. |
1113 SetExpressionPosition(stmt->enumerable()); | 1114 SetExpressionAsStatementPosition(stmt->enumerable()); |
1114 VisitForAccumulatorValue(stmt->enumerable()); | 1115 VisitForAccumulatorValue(stmt->enumerable()); |
1115 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 1116 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
1116 __ cmp(r3, ip); | 1117 __ cmp(r3, ip); |
1117 __ beq(&exit); | 1118 __ beq(&exit); |
1118 Register null_value = r7; | 1119 Register null_value = r7; |
1119 __ LoadRoot(null_value, Heap::kNullValueRootIndex); | 1120 __ LoadRoot(null_value, Heap::kNullValueRootIndex); |
1120 __ cmp(r3, null_value); | 1121 __ cmp(r3, null_value); |
1121 __ beq(&exit); | 1122 __ beq(&exit); |
1122 | 1123 |
1123 PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); | 1124 PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1209 __ LoadSmiLiteral(r4, Smi::FromInt(0)); // Zero indicates proxy | 1210 __ LoadSmiLiteral(r4, Smi::FromInt(0)); // Zero indicates proxy |
1210 __ bind(&non_proxy); | 1211 __ bind(&non_proxy); |
1211 __ Push(r4, r3); // Smi and array | 1212 __ Push(r4, r3); // Smi and array |
1212 __ LoadP(r4, FieldMemOperand(r3, FixedArray::kLengthOffset)); | 1213 __ LoadP(r4, FieldMemOperand(r3, FixedArray::kLengthOffset)); |
1213 __ LoadSmiLiteral(r3, Smi::FromInt(0)); | 1214 __ LoadSmiLiteral(r3, Smi::FromInt(0)); |
1214 __ Push(r4, r3); // Fixed array length (as smi) and initial index. | 1215 __ Push(r4, r3); // Fixed array length (as smi) and initial index. |
1215 | 1216 |
1216 // Generate code for doing the condition check. | 1217 // Generate code for doing the condition check. |
1217 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); | 1218 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); |
1218 __ bind(&loop); | 1219 __ bind(&loop); |
1219 SetExpressionPosition(stmt->each()); | 1220 SetExpressionAsStatementPosition(stmt->each()); |
1220 | 1221 |
1221 // Load the current count to r3, load the length to r4. | 1222 // Load the current count to r3, load the length to r4. |
1222 __ LoadP(r3, MemOperand(sp, 0 * kPointerSize)); | 1223 __ LoadP(r3, MemOperand(sp, 0 * kPointerSize)); |
1223 __ LoadP(r4, MemOperand(sp, 1 * kPointerSize)); | 1224 __ LoadP(r4, MemOperand(sp, 1 * kPointerSize)); |
1224 __ cmpl(r3, r4); // Compare to the array length. | 1225 __ cmpl(r3, r4); // Compare to the array length. |
1225 __ bge(loop_statement.break_label()); | 1226 __ bge(loop_statement.break_label()); |
1226 | 1227 |
1227 // Get the current entry of the array into register r6. | 1228 // Get the current entry of the array into register r6. |
1228 __ LoadP(r5, MemOperand(sp, 2 * kPointerSize)); | 1229 __ LoadP(r5, MemOperand(sp, 2 * kPointerSize)); |
1229 __ addi(r5, r5, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 1230 __ addi(r5, r5, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1456 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 1457 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
1457 } | 1458 } |
1458 } | 1459 } |
1459 __ b(done); | 1460 __ b(done); |
1460 } | 1461 } |
1461 } | 1462 } |
1462 | 1463 |
1463 | 1464 |
1464 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { | 1465 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
1465 // Record position before possible IC call. | 1466 // Record position before possible IC call. |
1466 SetSourcePosition(proxy->position()); | 1467 SetExpressionPosition(proxy); |
1467 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); | 1468 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); |
1468 Variable* var = proxy->var(); | 1469 Variable* var = proxy->var(); |
1469 | 1470 |
1470 // Three cases: global variables, lookup variables, and all other types of | 1471 // Three cases: global variables, lookup variables, and all other types of |
1471 // variables. | 1472 // variables. |
1472 switch (var->location()) { | 1473 switch (var->location()) { |
1473 case VariableLocation::GLOBAL: | 1474 case VariableLocation::GLOBAL: |
1474 case VariableLocation::UNALLOCATED: { | 1475 case VariableLocation::UNALLOCATED: { |
1475 Comment cmnt(masm_, "[ Global variable"); | 1476 Comment cmnt(masm_, "[ Global variable"); |
1476 __ LoadP(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 1477 __ LoadP(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1948 } else { | 1949 } else { |
1949 context()->Plug(r3); | 1950 context()->Plug(r3); |
1950 } | 1951 } |
1951 } | 1952 } |
1952 | 1953 |
1953 | 1954 |
1954 void FullCodeGenerator::VisitAssignment(Assignment* expr) { | 1955 void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
1955 DCHECK(expr->target()->IsValidReferenceExpression()); | 1956 DCHECK(expr->target()->IsValidReferenceExpression()); |
1956 | 1957 |
1957 Comment cmnt(masm_, "[ Assignment"); | 1958 Comment cmnt(masm_, "[ Assignment"); |
| 1959 SetExpressionPosition(expr, INSERT_BREAK); |
1958 | 1960 |
1959 Property* property = expr->target()->AsProperty(); | 1961 Property* property = expr->target()->AsProperty(); |
1960 LhsKind assign_type = Property::GetAssignType(property); | 1962 LhsKind assign_type = Property::GetAssignType(property); |
1961 | 1963 |
1962 // Evaluate LHS expression. | 1964 // Evaluate LHS expression. |
1963 switch (assign_type) { | 1965 switch (assign_type) { |
1964 case VARIABLE: | 1966 case VARIABLE: |
1965 // Nothing to do here. | 1967 // Nothing to do here. |
1966 break; | 1968 break; |
1967 case NAMED_PROPERTY: | 1969 case NAMED_PROPERTY: |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2041 EmitKeyedPropertyLoad(property); | 2043 EmitKeyedPropertyLoad(property); |
2042 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 2044 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
2043 break; | 2045 break; |
2044 } | 2046 } |
2045 } | 2047 } |
2046 | 2048 |
2047 Token::Value op = expr->binary_op(); | 2049 Token::Value op = expr->binary_op(); |
2048 __ push(r3); // Left operand goes on the stack. | 2050 __ push(r3); // Left operand goes on the stack. |
2049 VisitForAccumulatorValue(expr->value()); | 2051 VisitForAccumulatorValue(expr->value()); |
2050 | 2052 |
2051 SetSourcePosition(expr->position() + 1); | |
2052 AccumulatorValueContext context(this); | 2053 AccumulatorValueContext context(this); |
2053 if (ShouldInlineSmiCase(op)) { | 2054 if (ShouldInlineSmiCase(op)) { |
2054 EmitInlineSmiBinaryOp(expr->binary_operation(), op, expr->target(), | 2055 EmitInlineSmiBinaryOp(expr->binary_operation(), op, expr->target(), |
2055 expr->value()); | 2056 expr->value()); |
2056 } else { | 2057 } else { |
2057 EmitBinaryOp(expr->binary_operation(), op); | 2058 EmitBinaryOp(expr->binary_operation(), op); |
2058 } | 2059 } |
2059 | 2060 |
2060 // Deoptimization point in case the binary operation may have side effects. | 2061 // Deoptimization point in case the binary operation may have side effects. |
2061 PrepareForBailout(expr->binary_operation(), TOS_REG); | 2062 PrepareForBailout(expr->binary_operation(), TOS_REG); |
2062 } else { | 2063 } else { |
2063 VisitForAccumulatorValue(expr->value()); | 2064 VisitForAccumulatorValue(expr->value()); |
2064 } | 2065 } |
2065 | 2066 |
2066 // Record source position before possible IC call. | 2067 SetExpressionPosition(expr); |
2067 SetSourcePosition(expr->position()); | |
2068 | 2068 |
2069 // Store the value. | 2069 // Store the value. |
2070 switch (assign_type) { | 2070 switch (assign_type) { |
2071 case VARIABLE: | 2071 case VARIABLE: |
2072 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 2072 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
2073 expr->op(), expr->AssignmentSlot()); | 2073 expr->op(), expr->AssignmentSlot()); |
2074 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2074 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2075 context()->Plug(r3); | 2075 context()->Plug(r3); |
2076 break; | 2076 break; |
2077 case NAMED_PROPERTY: | 2077 case NAMED_PROPERTY: |
2078 EmitNamedPropertyAssignment(expr); | 2078 EmitNamedPropertyAssignment(expr); |
2079 break; | 2079 break; |
2080 case NAMED_SUPER_PROPERTY: | 2080 case NAMED_SUPER_PROPERTY: |
2081 EmitNamedSuperPropertyStore(property); | 2081 EmitNamedSuperPropertyStore(property); |
2082 context()->Plug(r3); | 2082 context()->Plug(r3); |
2083 break; | 2083 break; |
2084 case KEYED_SUPER_PROPERTY: | 2084 case KEYED_SUPER_PROPERTY: |
2085 EmitKeyedSuperPropertyStore(property); | 2085 EmitKeyedSuperPropertyStore(property); |
2086 context()->Plug(r3); | 2086 context()->Plug(r3); |
2087 break; | 2087 break; |
2088 case KEYED_PROPERTY: | 2088 case KEYED_PROPERTY: |
2089 EmitKeyedPropertyAssignment(expr); | 2089 EmitKeyedPropertyAssignment(expr); |
2090 break; | 2090 break; |
2091 } | 2091 } |
2092 } | 2092 } |
2093 | 2093 |
2094 | 2094 |
2095 void FullCodeGenerator::VisitYield(Yield* expr) { | 2095 void FullCodeGenerator::VisitYield(Yield* expr) { |
2096 Comment cmnt(masm_, "[ Yield"); | 2096 Comment cmnt(masm_, "[ Yield"); |
| 2097 SetExpressionPosition(expr); |
| 2098 |
2097 // Evaluate yielded value first; the initial iterator definition depends on | 2099 // Evaluate yielded value first; the initial iterator definition depends on |
2098 // this. It stays on the stack while we update the iterator. | 2100 // this. It stays on the stack while we update the iterator. |
2099 VisitForStackValue(expr->expression()); | 2101 VisitForStackValue(expr->expression()); |
2100 | 2102 |
2101 switch (expr->yield_kind()) { | 2103 switch (expr->yield_kind()) { |
2102 case Yield::kSuspend: | 2104 case Yield::kSuspend: |
2103 // Pop value from top-of-stack slot; box result into result register. | 2105 // Pop value from top-of-stack slot; box result into result register. |
2104 EmitCreateIteratorResult(false); | 2106 EmitCreateIteratorResult(false); |
2105 __ push(result_register()); | 2107 __ push(result_register()); |
2106 // Fall through. | 2108 // Fall through. |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2393 r0); | 2395 r0); |
2394 | 2396 |
2395 // Only the value field needs a write barrier, as the other values are in the | 2397 // Only the value field needs a write barrier, as the other values are in the |
2396 // root set. | 2398 // root set. |
2397 __ RecordWriteField(r3, JSGeneratorObject::kResultValuePropertyOffset, r5, r6, | 2399 __ RecordWriteField(r3, JSGeneratorObject::kResultValuePropertyOffset, r5, r6, |
2398 kLRHasBeenSaved, kDontSaveFPRegs); | 2400 kLRHasBeenSaved, kDontSaveFPRegs); |
2399 } | 2401 } |
2400 | 2402 |
2401 | 2403 |
2402 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2404 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
2403 SetSourcePosition(prop->position()); | 2405 SetExpressionPosition(prop); |
2404 Literal* key = prop->key()->AsLiteral(); | 2406 Literal* key = prop->key()->AsLiteral(); |
2405 DCHECK(!prop->IsSuperAccess()); | 2407 DCHECK(!prop->IsSuperAccess()); |
2406 | 2408 |
2407 __ mov(LoadDescriptor::NameRegister(), Operand(key->value())); | 2409 __ mov(LoadDescriptor::NameRegister(), Operand(key->value())); |
2408 __ mov(LoadDescriptor::SlotRegister(), | 2410 __ mov(LoadDescriptor::SlotRegister(), |
2409 Operand(SmiFromSlot(prop->PropertyFeedbackSlot()))); | 2411 Operand(SmiFromSlot(prop->PropertyFeedbackSlot()))); |
2410 CallLoadIC(NOT_CONTEXTUAL, language_mode()); | 2412 CallLoadIC(NOT_CONTEXTUAL, language_mode()); |
2411 } | 2413 } |
2412 | 2414 |
2413 | 2415 |
2414 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { | 2416 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { |
2415 // Stack: receiver, home_object. | 2417 // Stack: receiver, home_object. |
2416 SetSourcePosition(prop->position()); | 2418 SetExpressionPosition(prop); |
2417 Literal* key = prop->key()->AsLiteral(); | 2419 Literal* key = prop->key()->AsLiteral(); |
2418 DCHECK(!key->value()->IsSmi()); | 2420 DCHECK(!key->value()->IsSmi()); |
2419 DCHECK(prop->IsSuperAccess()); | 2421 DCHECK(prop->IsSuperAccess()); |
2420 | 2422 |
2421 __ Push(key->value()); | 2423 __ Push(key->value()); |
2422 __ Push(Smi::FromInt(language_mode())); | 2424 __ Push(Smi::FromInt(language_mode())); |
2423 __ CallRuntime(Runtime::kLoadFromSuper, 4); | 2425 __ CallRuntime(Runtime::kLoadFromSuper, 4); |
2424 } | 2426 } |
2425 | 2427 |
2426 | 2428 |
2427 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2429 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
2428 SetSourcePosition(prop->position()); | 2430 SetExpressionPosition(prop); |
2429 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code(); | 2431 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code(); |
2430 __ mov(LoadDescriptor::SlotRegister(), | 2432 __ mov(LoadDescriptor::SlotRegister(), |
2431 Operand(SmiFromSlot(prop->PropertyFeedbackSlot()))); | 2433 Operand(SmiFromSlot(prop->PropertyFeedbackSlot()))); |
2432 CallIC(ic); | 2434 CallIC(ic); |
2433 } | 2435 } |
2434 | 2436 |
2435 | 2437 |
2436 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { | 2438 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { |
2437 // Stack: receiver, home_object, key. | 2439 // Stack: receiver, home_object, key. |
| 2440 SetExpressionPosition(prop); |
2438 __ Push(Smi::FromInt(language_mode())); | 2441 __ Push(Smi::FromInt(language_mode())); |
2439 SetSourcePosition(prop->position()); | |
2440 | |
2441 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); | 2442 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); |
2442 } | 2443 } |
2443 | 2444 |
2444 | 2445 |
2445 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2446 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
2446 Token::Value op, | 2447 Token::Value op, |
2447 Expression* left_expr, | 2448 Expression* left_expr, |
2448 Expression* right_expr) { | 2449 Expression* right_expr) { |
2449 Label done, smi_case, stub_call; | 2450 Label done, smi_case, stub_call; |
2450 | 2451 |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2834 } | 2835 } |
2835 } | 2836 } |
2836 | 2837 |
2837 | 2838 |
2838 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2839 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
2839 // Assignment to a property, using a named store IC. | 2840 // Assignment to a property, using a named store IC. |
2840 Property* prop = expr->target()->AsProperty(); | 2841 Property* prop = expr->target()->AsProperty(); |
2841 DCHECK(prop != NULL); | 2842 DCHECK(prop != NULL); |
2842 DCHECK(prop->key()->IsLiteral()); | 2843 DCHECK(prop->key()->IsLiteral()); |
2843 | 2844 |
2844 // Record source code position before IC call. | |
2845 SetSourcePosition(expr->position()); | |
2846 __ mov(StoreDescriptor::NameRegister(), | 2845 __ mov(StoreDescriptor::NameRegister(), |
2847 Operand(prop->key()->AsLiteral()->value())); | 2846 Operand(prop->key()->AsLiteral()->value())); |
2848 __ pop(StoreDescriptor::ReceiverRegister()); | 2847 __ pop(StoreDescriptor::ReceiverRegister()); |
2849 if (FLAG_vector_stores) { | 2848 if (FLAG_vector_stores) { |
2850 EmitLoadStoreICSlot(expr->AssignmentSlot()); | 2849 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
2851 CallStoreIC(); | 2850 CallStoreIC(); |
2852 } else { | 2851 } else { |
2853 CallStoreIC(expr->AssignmentFeedbackId()); | 2852 CallStoreIC(expr->AssignmentFeedbackId()); |
2854 } | 2853 } |
2855 | 2854 |
(...skipping 27 matching lines...) Expand all Loading... |
2883 __ Push(r3); | 2882 __ Push(r3); |
2884 __ CallRuntime( | 2883 __ CallRuntime( |
2885 (is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict | 2884 (is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
2886 : Runtime::kStoreKeyedToSuper_Sloppy), | 2885 : Runtime::kStoreKeyedToSuper_Sloppy), |
2887 4); | 2886 4); |
2888 } | 2887 } |
2889 | 2888 |
2890 | 2889 |
2891 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2890 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2892 // Assignment to a property, using a keyed store IC. | 2891 // Assignment to a property, using a keyed store IC. |
2893 | |
2894 // Record source code position before IC call. | |
2895 SetSourcePosition(expr->position()); | |
2896 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); | 2892 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); |
2897 DCHECK(StoreDescriptor::ValueRegister().is(r3)); | 2893 DCHECK(StoreDescriptor::ValueRegister().is(r3)); |
2898 | 2894 |
2899 Handle<Code> ic = | 2895 Handle<Code> ic = |
2900 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2896 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
2901 if (FLAG_vector_stores) { | 2897 if (FLAG_vector_stores) { |
2902 EmitLoadStoreICSlot(expr->AssignmentSlot()); | 2898 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
2903 CallIC(ic); | 2899 CallIC(ic); |
2904 } else { | 2900 } else { |
2905 CallIC(ic, expr->AssignmentFeedbackId()); | 2901 CallIC(ic, expr->AssignmentFeedbackId()); |
2906 } | 2902 } |
2907 | 2903 |
2908 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2904 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2909 context()->Plug(r3); | 2905 context()->Plug(r3); |
2910 } | 2906 } |
2911 | 2907 |
2912 | 2908 |
2913 void FullCodeGenerator::VisitProperty(Property* expr) { | 2909 void FullCodeGenerator::VisitProperty(Property* expr) { |
2914 Comment cmnt(masm_, "[ Property"); | 2910 Comment cmnt(masm_, "[ Property"); |
| 2911 SetExpressionPosition(expr); |
| 2912 |
2915 Expression* key = expr->key(); | 2913 Expression* key = expr->key(); |
2916 | 2914 |
2917 if (key->IsPropertyName()) { | 2915 if (key->IsPropertyName()) { |
2918 if (!expr->IsSuperAccess()) { | 2916 if (!expr->IsSuperAccess()) { |
2919 VisitForAccumulatorValue(expr->obj()); | 2917 VisitForAccumulatorValue(expr->obj()); |
2920 __ Move(LoadDescriptor::ReceiverRegister(), r3); | 2918 __ Move(LoadDescriptor::ReceiverRegister(), r3); |
2921 EmitNamedPropertyLoad(expr); | 2919 EmitNamedPropertyLoad(expr); |
2922 } else { | 2920 } else { |
2923 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); | 2921 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); |
2924 VisitForStackValue( | 2922 VisitForStackValue( |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2984 | 2982 |
2985 EmitCall(expr, call_type); | 2983 EmitCall(expr, call_type); |
2986 } | 2984 } |
2987 | 2985 |
2988 | 2986 |
2989 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | 2987 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { |
2990 Expression* callee = expr->expression(); | 2988 Expression* callee = expr->expression(); |
2991 DCHECK(callee->IsProperty()); | 2989 DCHECK(callee->IsProperty()); |
2992 Property* prop = callee->AsProperty(); | 2990 Property* prop = callee->AsProperty(); |
2993 DCHECK(prop->IsSuperAccess()); | 2991 DCHECK(prop->IsSuperAccess()); |
| 2992 SetExpressionPosition(prop); |
2994 | 2993 |
2995 SetSourcePosition(prop->position()); | |
2996 Literal* key = prop->key()->AsLiteral(); | 2994 Literal* key = prop->key()->AsLiteral(); |
2997 DCHECK(!key->value()->IsSmi()); | 2995 DCHECK(!key->value()->IsSmi()); |
2998 // Load the function from the receiver. | 2996 // Load the function from the receiver. |
2999 const Register scratch = r4; | 2997 const Register scratch = r4; |
3000 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | 2998 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); |
3001 VisitForAccumulatorValue(super_ref->home_object()); | 2999 VisitForAccumulatorValue(super_ref->home_object()); |
3002 __ mr(scratch, r3); | 3000 __ mr(scratch, r3); |
3003 VisitForAccumulatorValue(super_ref->this_var()); | 3001 VisitForAccumulatorValue(super_ref->this_var()); |
3004 __ Push(scratch, r3, r3, scratch); | 3002 __ Push(scratch, r3, r3, scratch); |
3005 __ Push(key->value()); | 3003 __ Push(key->value()); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3046 EmitCall(expr, CallICState::METHOD); | 3044 EmitCall(expr, CallICState::METHOD); |
3047 } | 3045 } |
3048 | 3046 |
3049 | 3047 |
3050 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | 3048 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { |
3051 Expression* callee = expr->expression(); | 3049 Expression* callee = expr->expression(); |
3052 DCHECK(callee->IsProperty()); | 3050 DCHECK(callee->IsProperty()); |
3053 Property* prop = callee->AsProperty(); | 3051 Property* prop = callee->AsProperty(); |
3054 DCHECK(prop->IsSuperAccess()); | 3052 DCHECK(prop->IsSuperAccess()); |
3055 | 3053 |
3056 SetSourcePosition(prop->position()); | 3054 SetExpressionPosition(prop); |
3057 // Load the function from the receiver. | 3055 // Load the function from the receiver. |
3058 const Register scratch = r4; | 3056 const Register scratch = r4; |
3059 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | 3057 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); |
3060 VisitForAccumulatorValue(super_ref->home_object()); | 3058 VisitForAccumulatorValue(super_ref->home_object()); |
3061 __ mr(scratch, r3); | 3059 __ mr(scratch, r3); |
3062 VisitForAccumulatorValue(super_ref->this_var()); | 3060 VisitForAccumulatorValue(super_ref->this_var()); |
3063 __ Push(scratch, r3, r3, scratch); | 3061 __ Push(scratch, r3, r3, scratch); |
3064 VisitForStackValue(prop->key()); | 3062 VisitForStackValue(prop->key()); |
3065 __ Push(Smi::FromInt(language_mode())); | 3063 __ Push(Smi::FromInt(language_mode())); |
3066 | 3064 |
(...skipping 13 matching lines...) Expand all Loading... |
3080 // - target function | 3078 // - target function |
3081 // - this (receiver) | 3079 // - this (receiver) |
3082 EmitCall(expr, CallICState::METHOD); | 3080 EmitCall(expr, CallICState::METHOD); |
3083 } | 3081 } |
3084 | 3082 |
3085 | 3083 |
3086 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) { | 3084 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) { |
3087 // Load the arguments. | 3085 // Load the arguments. |
3088 ZoneList<Expression*>* args = expr->arguments(); | 3086 ZoneList<Expression*>* args = expr->arguments(); |
3089 int arg_count = args->length(); | 3087 int arg_count = args->length(); |
3090 { | 3088 for (int i = 0; i < arg_count; i++) { |
3091 PreservePositionScope scope(masm()->positions_recorder()); | 3089 VisitForStackValue(args->at(i)); |
3092 for (int i = 0; i < arg_count; i++) { | |
3093 VisitForStackValue(args->at(i)); | |
3094 } | |
3095 } | 3090 } |
3096 | 3091 |
3097 // Record source position of the IC call. | 3092 SetExpressionPosition(expr); |
3098 SetSourcePosition(expr->position()); | |
3099 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code(); | 3093 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code(); |
3100 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackICSlot())); | 3094 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackICSlot())); |
3101 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); | 3095 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); |
3102 // Don't assign a type feedback id to the IC, since type feedback is provided | 3096 // Don't assign a type feedback id to the IC, since type feedback is provided |
3103 // by the vector above. | 3097 // by the vector above. |
3104 CallIC(ic); | 3098 CallIC(ic); |
3105 | 3099 |
3106 RecordJSReturnSite(expr); | 3100 RecordJSReturnSite(expr); |
3107 // Restore context register. | 3101 // Restore context register. |
3108 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3102 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3147 | 3141 |
3148 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); | 3142 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); |
3149 } | 3143 } |
3150 | 3144 |
3151 | 3145 |
3152 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. | 3146 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. |
3153 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { | 3147 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { |
3154 VariableProxy* callee = expr->expression()->AsVariableProxy(); | 3148 VariableProxy* callee = expr->expression()->AsVariableProxy(); |
3155 if (callee->var()->IsLookupSlot()) { | 3149 if (callee->var()->IsLookupSlot()) { |
3156 Label slow, done; | 3150 Label slow, done; |
3157 SetSourcePosition(callee->position()); | 3151 SetExpressionPosition(callee); |
3158 { | 3152 // Generate code for loading from variables potentially shadowed by |
3159 PreservePositionScope scope(masm()->positions_recorder()); | 3153 // eval-introduced variables. |
3160 // Generate code for loading from variables potentially shadowed by | 3154 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); |
3161 // eval-introduced variables. | 3155 |
3162 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); | |
3163 } | |
3164 __ bind(&slow); | 3156 __ bind(&slow); |
3165 // Call the runtime to find the function to call (returned in r3) and | 3157 // Call the runtime to find the function to call (returned in r3) and |
3166 // the object holding it (returned in r4). | 3158 // the object holding it (returned in r4). |
3167 DCHECK(!context_register().is(r5)); | 3159 DCHECK(!context_register().is(r5)); |
3168 __ mov(r5, Operand(callee->name())); | 3160 __ mov(r5, Operand(callee->name())); |
3169 __ Push(context_register(), r5); | 3161 __ Push(context_register(), r5); |
3170 __ CallRuntime(Runtime::kLoadLookupSlot, 2); | 3162 __ CallRuntime(Runtime::kLoadLookupSlot, 2); |
3171 __ Push(r3, r4); // Function, receiver. | 3163 __ Push(r3, r4); // Function, receiver. |
3172 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); | 3164 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); |
3173 | 3165 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3206 Expression* callee = expr->expression(); | 3198 Expression* callee = expr->expression(); |
3207 Call::CallType call_type = expr->GetCallType(isolate()); | 3199 Call::CallType call_type = expr->GetCallType(isolate()); |
3208 | 3200 |
3209 if (call_type == Call::POSSIBLY_EVAL_CALL) { | 3201 if (call_type == Call::POSSIBLY_EVAL_CALL) { |
3210 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval | 3202 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval |
3211 // to resolve the function we need to call. Then we call the resolved | 3203 // to resolve the function we need to call. Then we call the resolved |
3212 // function using the given arguments. | 3204 // function using the given arguments. |
3213 ZoneList<Expression*>* args = expr->arguments(); | 3205 ZoneList<Expression*>* args = expr->arguments(); |
3214 int arg_count = args->length(); | 3206 int arg_count = args->length(); |
3215 | 3207 |
3216 { | 3208 PushCalleeAndWithBaseObject(expr); |
3217 PreservePositionScope pos_scope(masm()->positions_recorder()); | |
3218 PushCalleeAndWithBaseObject(expr); | |
3219 | 3209 |
3220 // Push the arguments. | 3210 // Push the arguments. |
3221 for (int i = 0; i < arg_count; i++) { | 3211 for (int i = 0; i < arg_count; i++) { |
3222 VisitForStackValue(args->at(i)); | 3212 VisitForStackValue(args->at(i)); |
3223 } | |
3224 | |
3225 // Push a copy of the function (found below the arguments) and | |
3226 // resolve eval. | |
3227 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); | |
3228 __ push(r4); | |
3229 EmitResolvePossiblyDirectEval(arg_count); | |
3230 | |
3231 // Touch up the stack with the resolved function. | |
3232 __ StoreP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); | |
3233 | |
3234 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); | |
3235 } | 3213 } |
3236 | 3214 |
| 3215 // Push a copy of the function (found below the arguments) and |
| 3216 // resolve eval. |
| 3217 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); |
| 3218 __ push(r4); |
| 3219 EmitResolvePossiblyDirectEval(arg_count); |
| 3220 |
| 3221 // Touch up the stack with the resolved function. |
| 3222 __ StoreP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); |
| 3223 |
| 3224 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); |
| 3225 |
3237 // Record source position for debugger. | 3226 // Record source position for debugger. |
3238 SetSourcePosition(expr->position()); | 3227 SetExpressionPosition(expr); |
3239 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | 3228 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
3240 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); | 3229 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); |
3241 __ CallStub(&stub); | 3230 __ CallStub(&stub); |
3242 RecordJSReturnSite(expr); | 3231 RecordJSReturnSite(expr); |
3243 // Restore context register. | 3232 // Restore context register. |
3244 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3233 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3245 context()->DropAndPlug(1, r3); | 3234 context()->DropAndPlug(1, r3); |
3246 } else if (call_type == Call::GLOBAL_CALL) { | 3235 } else if (call_type == Call::GLOBAL_CALL) { |
3247 EmitCallWithLoadIC(expr); | 3236 EmitCallWithLoadIC(expr); |
3248 | 3237 |
3249 } else if (call_type == Call::LOOKUP_SLOT_CALL) { | 3238 } else if (call_type == Call::LOOKUP_SLOT_CALL) { |
3250 // Call to a lookup slot (dynamically introduced variable). | 3239 // Call to a lookup slot (dynamically introduced variable). |
3251 PushCalleeAndWithBaseObject(expr); | 3240 PushCalleeAndWithBaseObject(expr); |
3252 EmitCall(expr); | 3241 EmitCall(expr); |
3253 } else if (call_type == Call::PROPERTY_CALL) { | 3242 } else if (call_type == Call::PROPERTY_CALL) { |
3254 Property* property = callee->AsProperty(); | 3243 Property* property = callee->AsProperty(); |
3255 bool is_named_call = property->key()->IsPropertyName(); | 3244 bool is_named_call = property->key()->IsPropertyName(); |
3256 if (property->IsSuperAccess()) { | 3245 if (property->IsSuperAccess()) { |
3257 if (is_named_call) { | 3246 if (is_named_call) { |
3258 EmitSuperCallWithLoadIC(expr); | 3247 EmitSuperCallWithLoadIC(expr); |
3259 } else { | 3248 } else { |
3260 EmitKeyedSuperCallWithLoadIC(expr); | 3249 EmitKeyedSuperCallWithLoadIC(expr); |
3261 } | 3250 } |
3262 } else { | 3251 } else { |
3263 { | 3252 VisitForStackValue(property->obj()); |
3264 PreservePositionScope scope(masm()->positions_recorder()); | |
3265 VisitForStackValue(property->obj()); | |
3266 } | |
3267 if (is_named_call) { | 3253 if (is_named_call) { |
3268 EmitCallWithLoadIC(expr); | 3254 EmitCallWithLoadIC(expr); |
3269 } else { | 3255 } else { |
3270 EmitKeyedCallWithLoadIC(expr, property->key()); | 3256 EmitKeyedCallWithLoadIC(expr, property->key()); |
3271 } | 3257 } |
3272 } | 3258 } |
3273 } else if (call_type == Call::SUPER_CALL) { | 3259 } else if (call_type == Call::SUPER_CALL) { |
3274 EmitSuperConstructorCall(expr); | 3260 EmitSuperConstructorCall(expr); |
3275 } else { | 3261 } else { |
3276 DCHECK(call_type == Call::OTHER_CALL); | 3262 DCHECK(call_type == Call::OTHER_CALL); |
3277 // Call to an arbitrary expression not handled specially above. | 3263 // Call to an arbitrary expression not handled specially above. |
3278 { | 3264 VisitForStackValue(callee); |
3279 PreservePositionScope scope(masm()->positions_recorder()); | |
3280 VisitForStackValue(callee); | |
3281 } | |
3282 __ LoadRoot(r4, Heap::kUndefinedValueRootIndex); | 3265 __ LoadRoot(r4, Heap::kUndefinedValueRootIndex); |
3283 __ push(r4); | 3266 __ push(r4); |
3284 // Emit function call. | 3267 // Emit function call. |
3285 EmitCall(expr); | 3268 EmitCall(expr); |
3286 } | 3269 } |
3287 | 3270 |
3288 #ifdef DEBUG | 3271 #ifdef DEBUG |
3289 // RecordJSReturnSite should have been called. | 3272 // RecordJSReturnSite should have been called. |
3290 DCHECK(expr->return_is_recorded_); | 3273 DCHECK(expr->return_is_recorded_); |
3291 #endif | 3274 #endif |
(...skipping 14 matching lines...) Expand all Loading... |
3306 | 3289 |
3307 // Push the arguments ("left-to-right") on the stack. | 3290 // Push the arguments ("left-to-right") on the stack. |
3308 ZoneList<Expression*>* args = expr->arguments(); | 3291 ZoneList<Expression*>* args = expr->arguments(); |
3309 int arg_count = args->length(); | 3292 int arg_count = args->length(); |
3310 for (int i = 0; i < arg_count; i++) { | 3293 for (int i = 0; i < arg_count; i++) { |
3311 VisitForStackValue(args->at(i)); | 3294 VisitForStackValue(args->at(i)); |
3312 } | 3295 } |
3313 | 3296 |
3314 // Call the construct call builtin that handles allocation and | 3297 // Call the construct call builtin that handles allocation and |
3315 // constructor invocation. | 3298 // constructor invocation. |
3316 SetSourcePosition(expr->position()); | 3299 SetExpressionPosition(expr); |
3317 | 3300 |
3318 // Load function and argument count into r4 and r3. | 3301 // Load function and argument count into r4 and r3. |
3319 __ mov(r3, Operand(arg_count)); | 3302 __ mov(r3, Operand(arg_count)); |
3320 __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize), r0); | 3303 __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize), r0); |
3321 | 3304 |
3322 // Record call targets in unoptimized code. | 3305 // Record call targets in unoptimized code. |
3323 if (FLAG_pretenuring_call_new) { | 3306 if (FLAG_pretenuring_call_new) { |
3324 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); | 3307 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); |
3325 DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() == | 3308 DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() == |
3326 expr->CallNewFeedbackSlot().ToInt() + 1); | 3309 expr->CallNewFeedbackSlot().ToInt() + 1); |
(...skipping 22 matching lines...) Expand all Loading... |
3349 | 3332 |
3350 // Push the arguments ("left-to-right") on the stack. | 3333 // Push the arguments ("left-to-right") on the stack. |
3351 ZoneList<Expression*>* args = expr->arguments(); | 3334 ZoneList<Expression*>* args = expr->arguments(); |
3352 int arg_count = args->length(); | 3335 int arg_count = args->length(); |
3353 for (int i = 0; i < arg_count; i++) { | 3336 for (int i = 0; i < arg_count; i++) { |
3354 VisitForStackValue(args->at(i)); | 3337 VisitForStackValue(args->at(i)); |
3355 } | 3338 } |
3356 | 3339 |
3357 // Call the construct call builtin that handles allocation and | 3340 // Call the construct call builtin that handles allocation and |
3358 // constructor invocation. | 3341 // constructor invocation. |
3359 SetSourcePosition(expr->position()); | 3342 SetExpressionPosition(expr); |
3360 | 3343 |
3361 // Load function and argument count into r1 and r0. | 3344 // Load function and argument count into r1 and r0. |
3362 __ mov(r3, Operand(arg_count)); | 3345 __ mov(r3, Operand(arg_count)); |
3363 __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize)); | 3346 __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize)); |
3364 | 3347 |
3365 // Record call targets in unoptimized code. | 3348 // Record call targets in unoptimized code. |
3366 if (FLAG_pretenuring_call_new) { | 3349 if (FLAG_pretenuring_call_new) { |
3367 UNREACHABLE(); | 3350 UNREACHABLE(); |
3368 /* TODO(dslomov): support pretenuring. | 3351 /* TODO(dslomov): support pretenuring. |
3369 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); | 3352 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); |
(...skipping 1388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4758 __ mov(LoadDescriptor::SlotRegister(), | 4741 __ mov(LoadDescriptor::SlotRegister(), |
4759 Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot()))); | 4742 Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot()))); |
4760 CallLoadIC(NOT_CONTEXTUAL); | 4743 CallLoadIC(NOT_CONTEXTUAL); |
4761 } | 4744 } |
4762 | 4745 |
4763 | 4746 |
4764 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 4747 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
4765 ZoneList<Expression*>* args = expr->arguments(); | 4748 ZoneList<Expression*>* args = expr->arguments(); |
4766 int arg_count = args->length(); | 4749 int arg_count = args->length(); |
4767 | 4750 |
4768 // Record source position of the IC call. | 4751 SetExpressionPosition(expr); |
4769 SetSourcePosition(expr->position()); | |
4770 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | 4752 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
4771 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); | 4753 __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); |
4772 __ CallStub(&stub); | 4754 __ CallStub(&stub); |
4773 } | 4755 } |
4774 | 4756 |
4775 | 4757 |
4776 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 4758 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
4777 ZoneList<Expression*>* args = expr->arguments(); | 4759 ZoneList<Expression*>* args = expr->arguments(); |
4778 int arg_count = args->length(); | 4760 int arg_count = args->length(); |
4779 | 4761 |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4933 default: | 4915 default: |
4934 UNREACHABLE(); | 4916 UNREACHABLE(); |
4935 } | 4917 } |
4936 } | 4918 } |
4937 | 4919 |
4938 | 4920 |
4939 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4921 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
4940 DCHECK(expr->expression()->IsValidReferenceExpression()); | 4922 DCHECK(expr->expression()->IsValidReferenceExpression()); |
4941 | 4923 |
4942 Comment cmnt(masm_, "[ CountOperation"); | 4924 Comment cmnt(masm_, "[ CountOperation"); |
4943 SetSourcePosition(expr->position()); | |
4944 | 4925 |
4945 Property* prop = expr->expression()->AsProperty(); | 4926 Property* prop = expr->expression()->AsProperty(); |
4946 LhsKind assign_type = Property::GetAssignType(prop); | 4927 LhsKind assign_type = Property::GetAssignType(prop); |
4947 | 4928 |
4948 // Evaluate expression and get value. | 4929 // Evaluate expression and get value. |
4949 if (assign_type == VARIABLE) { | 4930 if (assign_type == VARIABLE) { |
4950 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4931 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
4951 AccumulatorValueContext context(this); | 4932 AccumulatorValueContext context(this); |
4952 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4933 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
4953 } else { | 4934 } else { |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5089 __ StoreP(r3, MemOperand(sp, 3 * kPointerSize)); | 5070 __ StoreP(r3, MemOperand(sp, 3 * kPointerSize)); |
5090 break; | 5071 break; |
5091 } | 5072 } |
5092 } | 5073 } |
5093 } | 5074 } |
5094 | 5075 |
5095 __ bind(&stub_call); | 5076 __ bind(&stub_call); |
5096 __ mr(r4, r3); | 5077 __ mr(r4, r3); |
5097 __ LoadSmiLiteral(r3, Smi::FromInt(count_value)); | 5078 __ LoadSmiLiteral(r3, Smi::FromInt(count_value)); |
5098 | 5079 |
5099 // Record position before stub call. | 5080 SetExpressionPosition(expr); |
5100 SetSourcePosition(expr->position()); | |
5101 | 5081 |
5102 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD, | 5082 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD, |
5103 strength(language_mode())).code(); | 5083 strength(language_mode())).code(); |
5104 CallIC(code, expr->CountBinOpFeedbackId()); | 5084 CallIC(code, expr->CountBinOpFeedbackId()); |
5105 patch_site.EmitPatchInfo(); | 5085 patch_site.EmitPatchInfo(); |
5106 __ bind(&done); | 5086 __ bind(&done); |
5107 | 5087 |
5108 if (is_strong(language_mode())) { | 5088 if (is_strong(language_mode())) { |
5109 PrepareForBailoutForId(expr->ToNumberId(), TOS_REG); | 5089 PrepareForBailoutForId(expr->ToNumberId(), TOS_REG); |
5110 } | 5090 } |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5309 Split(eq, if_true, if_false, fall_through, cr0); | 5289 Split(eq, if_true, if_false, fall_through, cr0); |
5310 } else { | 5290 } else { |
5311 if (if_false != fall_through) __ b(if_false); | 5291 if (if_false != fall_through) __ b(if_false); |
5312 } | 5292 } |
5313 context()->Plug(if_true, if_false); | 5293 context()->Plug(if_true, if_false); |
5314 } | 5294 } |
5315 | 5295 |
5316 | 5296 |
5317 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { | 5297 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { |
5318 Comment cmnt(masm_, "[ CompareOperation"); | 5298 Comment cmnt(masm_, "[ CompareOperation"); |
5319 SetSourcePosition(expr->position()); | 5299 SetExpressionPosition(expr); |
5320 | 5300 |
5321 // First we try a fast inlined version of the compare when one of | 5301 // First we try a fast inlined version of the compare when one of |
5322 // the operands is a literal. | 5302 // the operands is a literal. |
5323 if (TryLiteralCompare(expr)) return; | 5303 if (TryLiteralCompare(expr)) return; |
5324 | 5304 |
5325 // Always perform the comparison for its control flow. Pack the result | 5305 // Always perform the comparison for its control flow. Pack the result |
5326 // into the expression's context after the comparison is performed. | 5306 // into the expression's context after the comparison is performed. |
5327 Label materialize_true, materialize_false; | 5307 Label materialize_true, materialize_false; |
5328 Label* if_true = NULL; | 5308 Label* if_true = NULL; |
5329 Label* if_false = NULL; | 5309 Label* if_false = NULL; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5363 JumpPatchSite patch_site(masm_); | 5343 JumpPatchSite patch_site(masm_); |
5364 if (inline_smi_code) { | 5344 if (inline_smi_code) { |
5365 Label slow_case; | 5345 Label slow_case; |
5366 __ orx(r5, r3, r4); | 5346 __ orx(r5, r3, r4); |
5367 patch_site.EmitJumpIfNotSmi(r5, &slow_case); | 5347 patch_site.EmitJumpIfNotSmi(r5, &slow_case); |
5368 __ cmp(r4, r3); | 5348 __ cmp(r4, r3); |
5369 Split(cond, if_true, if_false, NULL); | 5349 Split(cond, if_true, if_false, NULL); |
5370 __ bind(&slow_case); | 5350 __ bind(&slow_case); |
5371 } | 5351 } |
5372 | 5352 |
5373 // Record position and call the compare IC. | |
5374 SetSourcePosition(expr->position()); | |
5375 Handle<Code> ic = CodeFactory::CompareIC( | 5353 Handle<Code> ic = CodeFactory::CompareIC( |
5376 isolate(), op, strength(language_mode())).code(); | 5354 isolate(), op, strength(language_mode())).code(); |
5377 CallIC(ic, expr->CompareOperationFeedbackId()); | 5355 CallIC(ic, expr->CompareOperationFeedbackId()); |
5378 patch_site.EmitPatchInfo(); | 5356 patch_site.EmitPatchInfo(); |
5379 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 5357 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
5380 __ cmpi(r3, Operand::Zero()); | 5358 __ cmpi(r3, Operand::Zero()); |
5381 Split(cond, if_true, if_false, fall_through); | 5359 Split(cond, if_true, if_false, fall_through); |
5382 } | 5360 } |
5383 } | 5361 } |
5384 | 5362 |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5595 return ON_STACK_REPLACEMENT; | 5573 return ON_STACK_REPLACEMENT; |
5596 } | 5574 } |
5597 | 5575 |
5598 DCHECK(interrupt_address == | 5576 DCHECK(interrupt_address == |
5599 isolate->builtins()->OsrAfterStackCheck()->entry()); | 5577 isolate->builtins()->OsrAfterStackCheck()->entry()); |
5600 return OSR_AFTER_STACK_CHECK; | 5578 return OSR_AFTER_STACK_CHECK; |
5601 } | 5579 } |
5602 } // namespace internal | 5580 } // namespace internal |
5603 } // namespace v8 | 5581 } // namespace v8 |
5604 #endif // V8_TARGET_ARCH_PPC | 5582 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |