| 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_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
| 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 1946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1957 EmitKeyedPropertyLoad(property); | 1957 EmitKeyedPropertyLoad(property); |
| 1958 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 1958 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
| 1959 break; | 1959 break; |
| 1960 } | 1960 } |
| 1961 } | 1961 } |
| 1962 | 1962 |
| 1963 Token::Value op = expr->binary_op(); | 1963 Token::Value op = expr->binary_op(); |
| 1964 __ push(eax); // Left operand goes on the stack. | 1964 __ push(eax); // Left operand goes on the stack. |
| 1965 VisitForAccumulatorValue(expr->value()); | 1965 VisitForAccumulatorValue(expr->value()); |
| 1966 | 1966 |
| 1967 OverwriteMode mode = expr->value()->ResultOverwriteAllowed() | |
| 1968 ? OVERWRITE_RIGHT | |
| 1969 : NO_OVERWRITE; | |
| 1970 SetSourcePosition(expr->position() + 1); | 1967 SetSourcePosition(expr->position() + 1); |
| 1971 if (ShouldInlineSmiCase(op)) { | 1968 if (ShouldInlineSmiCase(op)) { |
| 1972 EmitInlineSmiBinaryOp(expr->binary_operation(), | 1969 EmitInlineSmiBinaryOp(expr->binary_operation(), |
| 1973 op, | 1970 op, |
| 1974 mode, | |
| 1975 expr->target(), | 1971 expr->target(), |
| 1976 expr->value()); | 1972 expr->value()); |
| 1977 } else { | 1973 } else { |
| 1978 EmitBinaryOp(expr->binary_operation(), op, mode); | 1974 EmitBinaryOp(expr->binary_operation(), op); |
| 1979 } | 1975 } |
| 1980 | 1976 |
| 1981 // Deoptimization point in case the binary operation may have side effects. | 1977 // Deoptimization point in case the binary operation may have side effects. |
| 1982 PrepareForBailout(expr->binary_operation(), TOS_REG); | 1978 PrepareForBailout(expr->binary_operation(), TOS_REG); |
| 1983 } else { | 1979 } else { |
| 1984 VisitForAccumulatorValue(expr->value()); | 1980 VisitForAccumulatorValue(expr->value()); |
| 1985 } | 1981 } |
| 1986 | 1982 |
| 1987 // Record source position before possible IC call. | 1983 // Record source position before possible IC call. |
| 1988 SetSourcePosition(expr->position()); | 1984 SetSourcePosition(expr->position()); |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2349 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { | 2345 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { |
| 2350 // Stack: receiver, home_object, key. | 2346 // Stack: receiver, home_object, key. |
| 2351 SetSourcePosition(prop->position()); | 2347 SetSourcePosition(prop->position()); |
| 2352 | 2348 |
| 2353 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3); | 2349 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3); |
| 2354 } | 2350 } |
| 2355 | 2351 |
| 2356 | 2352 |
| 2357 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2353 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
| 2358 Token::Value op, | 2354 Token::Value op, |
| 2359 OverwriteMode mode, | |
| 2360 Expression* left, | 2355 Expression* left, |
| 2361 Expression* right) { | 2356 Expression* right) { |
| 2362 // Do combined smi check of the operands. Left operand is on the | 2357 // Do combined smi check of the operands. Left operand is on the |
| 2363 // stack. Right operand is in eax. | 2358 // stack. Right operand is in eax. |
| 2364 Label smi_case, done, stub_call; | 2359 Label smi_case, done, stub_call; |
| 2365 __ pop(edx); | 2360 __ pop(edx); |
| 2366 __ mov(ecx, eax); | 2361 __ mov(ecx, eax); |
| 2367 __ or_(eax, edx); | 2362 __ or_(eax, edx); |
| 2368 JumpPatchSite patch_site(masm_); | 2363 JumpPatchSite patch_site(masm_); |
| 2369 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); | 2364 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); |
| 2370 | 2365 |
| 2371 __ bind(&stub_call); | 2366 __ bind(&stub_call); |
| 2372 __ mov(eax, ecx); | 2367 __ mov(eax, ecx); |
| 2373 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code(); | 2368 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); |
| 2374 CallIC(code, expr->BinaryOperationFeedbackId()); | 2369 CallIC(code, expr->BinaryOperationFeedbackId()); |
| 2375 patch_site.EmitPatchInfo(); | 2370 patch_site.EmitPatchInfo(); |
| 2376 __ jmp(&done, Label::kNear); | 2371 __ jmp(&done, Label::kNear); |
| 2377 | 2372 |
| 2378 // Smi case. | 2373 // Smi case. |
| 2379 __ bind(&smi_case); | 2374 __ bind(&smi_case); |
| 2380 __ mov(eax, edx); // Copy left operand in case of a stub call. | 2375 __ mov(eax, edx); // Copy left operand in case of a stub call. |
| 2381 | 2376 |
| 2382 switch (op) { | 2377 switch (op) { |
| 2383 case Token::SAR: | 2378 case Token::SAR: |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2495 } | 2490 } |
| 2496 | 2491 |
| 2497 // prototype | 2492 // prototype |
| 2498 __ CallRuntime(Runtime::kToFastProperties, 1); | 2493 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 2499 | 2494 |
| 2500 // constructor | 2495 // constructor |
| 2501 __ CallRuntime(Runtime::kToFastProperties, 1); | 2496 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 2502 } | 2497 } |
| 2503 | 2498 |
| 2504 | 2499 |
| 2505 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 2500 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) { |
| 2506 Token::Value op, | |
| 2507 OverwriteMode mode) { | |
| 2508 __ pop(edx); | 2501 __ pop(edx); |
| 2509 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code(); | 2502 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code(); |
| 2510 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2503 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
| 2511 CallIC(code, expr->BinaryOperationFeedbackId()); | 2504 CallIC(code, expr->BinaryOperationFeedbackId()); |
| 2512 patch_site.EmitPatchInfo(); | 2505 patch_site.EmitPatchInfo(); |
| 2513 context()->Plug(eax); | 2506 context()->Plug(eax); |
| 2514 } | 2507 } |
| 2515 | 2508 |
| 2516 | 2509 |
| 2517 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2510 void FullCodeGenerator::EmitAssignment(Expression* expr) { |
| 2518 DCHECK(expr->IsValidReferenceExpression()); | 2511 DCHECK(expr->IsValidReferenceExpression()); |
| 2519 | 2512 |
| (...skipping 2251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4771 } | 4764 } |
| 4772 } | 4765 } |
| 4773 | 4766 |
| 4774 // Record position before stub call. | 4767 // Record position before stub call. |
| 4775 SetSourcePosition(expr->position()); | 4768 SetSourcePosition(expr->position()); |
| 4776 | 4769 |
| 4777 // Call stub for +1/-1. | 4770 // Call stub for +1/-1. |
| 4778 __ bind(&stub_call); | 4771 __ bind(&stub_call); |
| 4779 __ mov(edx, eax); | 4772 __ mov(edx, eax); |
| 4780 __ mov(eax, Immediate(Smi::FromInt(1))); | 4773 __ mov(eax, Immediate(Smi::FromInt(1))); |
| 4781 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), expr->binary_op(), | 4774 Handle<Code> code = |
| 4782 NO_OVERWRITE).code(); | 4775 CodeFactory::BinaryOpIC(isolate(), expr->binary_op()).code(); |
| 4783 CallIC(code, expr->CountBinOpFeedbackId()); | 4776 CallIC(code, expr->CountBinOpFeedbackId()); |
| 4784 patch_site.EmitPatchInfo(); | 4777 patch_site.EmitPatchInfo(); |
| 4785 __ bind(&done); | 4778 __ bind(&done); |
| 4786 | 4779 |
| 4787 // Store the value returned in eax. | 4780 // Store the value returned in eax. |
| 4788 switch (assign_type) { | 4781 switch (assign_type) { |
| 4789 case VARIABLE: | 4782 case VARIABLE: |
| 4790 if (expr->is_postfix()) { | 4783 if (expr->is_postfix()) { |
| 4791 // Perform the assignment as if via '='. | 4784 // Perform the assignment as if via '='. |
| 4792 { EffectContext context(this); | 4785 { EffectContext context(this); |
| (...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5299 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 5292 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
| 5300 Assembler::target_address_at(call_target_address, | 5293 Assembler::target_address_at(call_target_address, |
| 5301 unoptimized_code)); | 5294 unoptimized_code)); |
| 5302 return OSR_AFTER_STACK_CHECK; | 5295 return OSR_AFTER_STACK_CHECK; |
| 5303 } | 5296 } |
| 5304 | 5297 |
| 5305 | 5298 |
| 5306 } } // namespace v8::internal | 5299 } } // namespace v8::internal |
| 5307 | 5300 |
| 5308 #endif // V8_TARGET_ARCH_IA32 | 5301 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |