OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_ARM | 7 #if V8_TARGET_ARCH_ARM |
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 2023 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2034 EmitKeyedPropertyLoad(property); | 2034 EmitKeyedPropertyLoad(property); |
2035 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 2035 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
2036 break; | 2036 break; |
2037 } | 2037 } |
2038 } | 2038 } |
2039 | 2039 |
2040 Token::Value op = expr->binary_op(); | 2040 Token::Value op = expr->binary_op(); |
2041 __ push(r0); // Left operand goes on the stack. | 2041 __ push(r0); // Left operand goes on the stack. |
2042 VisitForAccumulatorValue(expr->value()); | 2042 VisitForAccumulatorValue(expr->value()); |
2043 | 2043 |
2044 OverwriteMode mode = expr->value()->ResultOverwriteAllowed() | |
2045 ? OVERWRITE_RIGHT | |
2046 : NO_OVERWRITE; | |
2047 SetSourcePosition(expr->position() + 1); | 2044 SetSourcePosition(expr->position() + 1); |
2048 AccumulatorValueContext context(this); | 2045 AccumulatorValueContext context(this); |
2049 if (ShouldInlineSmiCase(op)) { | 2046 if (ShouldInlineSmiCase(op)) { |
2050 EmitInlineSmiBinaryOp(expr->binary_operation(), | 2047 EmitInlineSmiBinaryOp(expr->binary_operation(), |
2051 op, | 2048 op, |
2052 mode, | |
2053 expr->target(), | 2049 expr->target(), |
2054 expr->value()); | 2050 expr->value()); |
2055 } else { | 2051 } else { |
2056 EmitBinaryOp(expr->binary_operation(), op, mode); | 2052 EmitBinaryOp(expr->binary_operation(), op); |
2057 } | 2053 } |
2058 | 2054 |
2059 // Deoptimization point in case the binary operation may have side effects. | 2055 // Deoptimization point in case the binary operation may have side effects. |
2060 PrepareForBailout(expr->binary_operation(), TOS_REG); | 2056 PrepareForBailout(expr->binary_operation(), TOS_REG); |
2061 } else { | 2057 } else { |
2062 VisitForAccumulatorValue(expr->value()); | 2058 VisitForAccumulatorValue(expr->value()); |
2063 } | 2059 } |
2064 | 2060 |
2065 // Record source position before possible IC call. | 2061 // Record source position before possible IC call. |
2066 SetSourcePosition(expr->position()); | 2062 SetSourcePosition(expr->position()); |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2437 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { | 2433 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { |
2438 // Stack: receiver, home_object, key. | 2434 // Stack: receiver, home_object, key. |
2439 SetSourcePosition(prop->position()); | 2435 SetSourcePosition(prop->position()); |
2440 | 2436 |
2441 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3); | 2437 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3); |
2442 } | 2438 } |
2443 | 2439 |
2444 | 2440 |
2445 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2441 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
2446 Token::Value op, | 2442 Token::Value op, |
2447 OverwriteMode mode, | |
2448 Expression* left_expr, | 2443 Expression* left_expr, |
2449 Expression* right_expr) { | 2444 Expression* right_expr) { |
2450 Label done, smi_case, stub_call; | 2445 Label done, smi_case, stub_call; |
2451 | 2446 |
2452 Register scratch1 = r2; | 2447 Register scratch1 = r2; |
2453 Register scratch2 = r3; | 2448 Register scratch2 = r3; |
2454 | 2449 |
2455 // Get the arguments. | 2450 // Get the arguments. |
2456 Register left = r1; | 2451 Register left = r1; |
2457 Register right = r0; | 2452 Register right = r0; |
2458 __ pop(left); | 2453 __ pop(left); |
2459 | 2454 |
2460 // Perform combined smi check on both operands. | 2455 // Perform combined smi check on both operands. |
2461 __ orr(scratch1, left, Operand(right)); | 2456 __ orr(scratch1, left, Operand(right)); |
2462 STATIC_ASSERT(kSmiTag == 0); | 2457 STATIC_ASSERT(kSmiTag == 0); |
2463 JumpPatchSite patch_site(masm_); | 2458 JumpPatchSite patch_site(masm_); |
2464 patch_site.EmitJumpIfSmi(scratch1, &smi_case); | 2459 patch_site.EmitJumpIfSmi(scratch1, &smi_case); |
2465 | 2460 |
2466 __ bind(&stub_call); | 2461 __ bind(&stub_call); |
2467 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code(); | 2462 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); |
2468 CallIC(code, expr->BinaryOperationFeedbackId()); | 2463 CallIC(code, expr->BinaryOperationFeedbackId()); |
2469 patch_site.EmitPatchInfo(); | 2464 patch_site.EmitPatchInfo(); |
2470 __ jmp(&done); | 2465 __ jmp(&done); |
2471 | 2466 |
2472 __ bind(&smi_case); | 2467 __ bind(&smi_case); |
2473 // Smi case. This code works the same way as the smi-smi case in the type | 2468 // Smi case. This code works the same way as the smi-smi case in the type |
2474 // recording binary operation stub, see | 2469 // recording binary operation stub, see |
2475 switch (op) { | 2470 switch (op) { |
2476 case Token::SAR: | 2471 case Token::SAR: |
2477 __ GetLeastBitsFromSmi(scratch1, right, 5); | 2472 __ GetLeastBitsFromSmi(scratch1, right, 5); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2589 } | 2584 } |
2590 | 2585 |
2591 // prototype | 2586 // prototype |
2592 __ CallRuntime(Runtime::kToFastProperties, 1); | 2587 __ CallRuntime(Runtime::kToFastProperties, 1); |
2593 | 2588 |
2594 // constructor | 2589 // constructor |
2595 __ CallRuntime(Runtime::kToFastProperties, 1); | 2590 __ CallRuntime(Runtime::kToFastProperties, 1); |
2596 } | 2591 } |
2597 | 2592 |
2598 | 2593 |
2599 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 2594 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { |
2600 Token::Value op, | |
2601 OverwriteMode mode) { | |
2602 __ pop(r1); | 2595 __ pop(r1); |
2603 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code(); | 2596 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); |
2604 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2597 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
2605 CallIC(code, expr->BinaryOperationFeedbackId()); | 2598 CallIC(code, expr->BinaryOperationFeedbackId()); |
2606 patch_site.EmitPatchInfo(); | 2599 patch_site.EmitPatchInfo(); |
2607 context()->Plug(r0); | 2600 context()->Plug(r0); |
2608 } | 2601 } |
2609 | 2602 |
2610 | 2603 |
2611 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2604 void FullCodeGenerator::EmitAssignment(Expression* expr) { |
2612 DCHECK(expr->IsValidReferenceExpression()); | 2605 DCHECK(expr->IsValidReferenceExpression()); |
2613 | 2606 |
(...skipping 2225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4839 } | 4832 } |
4840 | 4833 |
4841 | 4834 |
4842 __ bind(&stub_call); | 4835 __ bind(&stub_call); |
4843 __ mov(r1, r0); | 4836 __ mov(r1, r0); |
4844 __ mov(r0, Operand(Smi::FromInt(count_value))); | 4837 __ mov(r0, Operand(Smi::FromInt(count_value))); |
4845 | 4838 |
4846 // Record position before stub call. | 4839 // Record position before stub call. |
4847 SetSourcePosition(expr->position()); | 4840 SetSourcePosition(expr->position()); |
4848 | 4841 |
4849 Handle<Code> code = | 4842 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD).code(); |
4850 CodeFactory::BinaryOpIC(isolate(), Token::ADD, NO_OVERWRITE).code(); | |
4851 CallIC(code, expr->CountBinOpFeedbackId()); | 4843 CallIC(code, expr->CountBinOpFeedbackId()); |
4852 patch_site.EmitPatchInfo(); | 4844 patch_site.EmitPatchInfo(); |
4853 __ bind(&done); | 4845 __ bind(&done); |
4854 | 4846 |
4855 // Store the value returned in r0. | 4847 // Store the value returned in r0. |
4856 switch (assign_type) { | 4848 switch (assign_type) { |
4857 case VARIABLE: | 4849 case VARIABLE: |
4858 if (expr->is_postfix()) { | 4850 if (expr->is_postfix()) { |
4859 { EffectContext context(this); | 4851 { EffectContext context(this); |
4860 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4852 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
(...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5434 | 5426 |
5435 DCHECK(interrupt_address == | 5427 DCHECK(interrupt_address == |
5436 isolate->builtins()->OsrAfterStackCheck()->entry()); | 5428 isolate->builtins()->OsrAfterStackCheck()->entry()); |
5437 return OSR_AFTER_STACK_CHECK; | 5429 return OSR_AFTER_STACK_CHECK; |
5438 } | 5430 } |
5439 | 5431 |
5440 | 5432 |
5441 } } // namespace v8::internal | 5433 } } // namespace v8::internal |
5442 | 5434 |
5443 #endif // V8_TARGET_ARCH_ARM | 5435 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |