| 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 |