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_X64 | 7 #if V8_TARGET_ARCH_X64 |
8 | 8 |
| 9 #include "src/code-factory.h" |
9 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 11 #include "src/codegen.h" |
11 #include "src/compiler.h" | 12 #include "src/compiler.h" |
12 #include "src/debug.h" | 13 #include "src/debug.h" |
13 #include "src/full-codegen.h" | 14 #include "src/full-codegen.h" |
14 #include "src/isolate-inl.h" | 15 #include "src/isolate-inl.h" |
15 #include "src/parser.h" | 16 #include "src/parser.h" |
16 #include "src/scopes.h" | 17 #include "src/scopes.h" |
17 | 18 |
18 namespace v8 { | 19 namespace v8 { |
(...skipping 984 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1003 | 1004 |
1004 __ cmpp(rdx, rax); | 1005 __ cmpp(rdx, rax); |
1005 __ j(not_equal, &next_test); | 1006 __ j(not_equal, &next_test); |
1006 __ Drop(1); // Switch value is no longer needed. | 1007 __ Drop(1); // Switch value is no longer needed. |
1007 __ jmp(clause->body_target()); | 1008 __ jmp(clause->body_target()); |
1008 __ bind(&slow_case); | 1009 __ bind(&slow_case); |
1009 } | 1010 } |
1010 | 1011 |
1011 // Record position before stub call for type feedback. | 1012 // Record position before stub call for type feedback. |
1012 SetSourcePosition(clause->position()); | 1013 SetSourcePosition(clause->position()); |
1013 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); | 1014 Handle<Code> ic = |
| 1015 CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code(); |
1014 CallIC(ic, clause->CompareId()); | 1016 CallIC(ic, clause->CompareId()); |
1015 patch_site.EmitPatchInfo(); | 1017 patch_site.EmitPatchInfo(); |
1016 | 1018 |
1017 Label skip; | 1019 Label skip; |
1018 __ jmp(&skip, Label::kNear); | 1020 __ jmp(&skip, Label::kNear); |
1019 PrepareForBailout(clause, TOS_REG); | 1021 PrepareForBailout(clause, TOS_REG); |
1020 __ CompareRoot(rax, Heap::kTrueValueRootIndex); | 1022 __ CompareRoot(rax, Heap::kTrueValueRootIndex); |
1021 __ j(not_equal, &next_test); | 1023 __ j(not_equal, &next_test); |
1022 __ Drop(1); | 1024 __ Drop(1); |
1023 __ jmp(clause->body_target()); | 1025 __ jmp(clause->body_target()); |
(...skipping 1026 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2050 __ Push(Operand(rsp, 2 * kPointerSize)); // iter | 2052 __ Push(Operand(rsp, 2 * kPointerSize)); // iter |
2051 __ Push(rax); // received | 2053 __ Push(rax); // received |
2052 | 2054 |
2053 // result = receiver[f](arg); | 2055 // result = receiver[f](arg); |
2054 __ bind(&l_call); | 2056 __ bind(&l_call); |
2055 __ movp(load_receiver, Operand(rsp, kPointerSize)); | 2057 __ movp(load_receiver, Operand(rsp, kPointerSize)); |
2056 if (FLAG_vector_ics) { | 2058 if (FLAG_vector_ics) { |
2057 __ Move(VectorLoadICDescriptor::SlotRegister(), | 2059 __ Move(VectorLoadICDescriptor::SlotRegister(), |
2058 Smi::FromInt(expr->KeyedLoadFeedbackSlot())); | 2060 Smi::FromInt(expr->KeyedLoadFeedbackSlot())); |
2059 } | 2061 } |
2060 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2062 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); |
2061 CallIC(ic, TypeFeedbackId::None()); | 2063 CallIC(ic, TypeFeedbackId::None()); |
2062 __ movp(rdi, rax); | 2064 __ movp(rdi, rax); |
2063 __ movp(Operand(rsp, 2 * kPointerSize), rdi); | 2065 __ movp(Operand(rsp, 2 * kPointerSize), rdi); |
2064 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); | 2066 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); |
2065 __ CallStub(&stub); | 2067 __ CallStub(&stub); |
2066 | 2068 |
2067 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 2069 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
2068 __ Drop(1); // The function is still on the stack; drop it. | 2070 __ Drop(1); // The function is still on the stack; drop it. |
2069 | 2071 |
2070 // if (!result.done) goto l_try; | 2072 // if (!result.done) goto l_try; |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2255 Smi::FromInt(prop->PropertyFeedbackSlot())); | 2257 Smi::FromInt(prop->PropertyFeedbackSlot())); |
2256 CallLoadIC(NOT_CONTEXTUAL); | 2258 CallLoadIC(NOT_CONTEXTUAL); |
2257 } else { | 2259 } else { |
2258 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); | 2260 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
2259 } | 2261 } |
2260 } | 2262 } |
2261 | 2263 |
2262 | 2264 |
2263 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2265 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
2264 SetSourcePosition(prop->position()); | 2266 SetSourcePosition(prop->position()); |
2265 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2267 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); |
2266 if (FLAG_vector_ics) { | 2268 if (FLAG_vector_ics) { |
2267 __ Move(VectorLoadICDescriptor::SlotRegister(), | 2269 __ Move(VectorLoadICDescriptor::SlotRegister(), |
2268 Smi::FromInt(prop->PropertyFeedbackSlot())); | 2270 Smi::FromInt(prop->PropertyFeedbackSlot())); |
2269 CallIC(ic); | 2271 CallIC(ic); |
2270 } else { | 2272 } else { |
2271 CallIC(ic, prop->PropertyFeedbackId()); | 2273 CallIC(ic, prop->PropertyFeedbackId()); |
2272 } | 2274 } |
2273 } | 2275 } |
2274 | 2276 |
2275 | 2277 |
2276 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2278 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
2277 Token::Value op, | 2279 Token::Value op, |
2278 OverwriteMode mode, | 2280 OverwriteMode mode, |
2279 Expression* left, | 2281 Expression* left, |
2280 Expression* right) { | 2282 Expression* right) { |
2281 // Do combined smi check of the operands. Left operand is on the | 2283 // Do combined smi check of the operands. Left operand is on the |
2282 // stack (popped into rdx). Right operand is in rax but moved into | 2284 // stack (popped into rdx). Right operand is in rax but moved into |
2283 // rcx to make the shifts easier. | 2285 // rcx to make the shifts easier. |
2284 Label done, stub_call, smi_case; | 2286 Label done, stub_call, smi_case; |
2285 __ Pop(rdx); | 2287 __ Pop(rdx); |
2286 __ movp(rcx, rax); | 2288 __ movp(rcx, rax); |
2287 __ orp(rax, rdx); | 2289 __ orp(rax, rdx); |
2288 JumpPatchSite patch_site(masm_); | 2290 JumpPatchSite patch_site(masm_); |
2289 patch_site.EmitJumpIfSmi(rax, &smi_case, Label::kNear); | 2291 patch_site.EmitJumpIfSmi(rax, &smi_case, Label::kNear); |
2290 | 2292 |
2291 __ bind(&stub_call); | 2293 __ bind(&stub_call); |
2292 __ movp(rax, rcx); | 2294 __ movp(rax, rcx); |
2293 BinaryOpICStub stub(isolate(), op, mode); | 2295 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code(); |
2294 CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId()); | 2296 CallIC(code, expr->BinaryOperationFeedbackId()); |
2295 patch_site.EmitPatchInfo(); | 2297 patch_site.EmitPatchInfo(); |
2296 __ jmp(&done, Label::kNear); | 2298 __ jmp(&done, Label::kNear); |
2297 | 2299 |
2298 __ bind(&smi_case); | 2300 __ bind(&smi_case); |
2299 switch (op) { | 2301 switch (op) { |
2300 case Token::SAR: | 2302 case Token::SAR: |
2301 __ SmiShiftArithmeticRight(rax, rdx, rcx); | 2303 __ SmiShiftArithmeticRight(rax, rdx, rcx); |
2302 break; | 2304 break; |
2303 case Token::SHL: | 2305 case Token::SHL: |
2304 __ SmiShiftLeft(rax, rdx, rcx, &stub_call); | 2306 __ SmiShiftLeft(rax, rdx, rcx, &stub_call); |
(...skipping 26 matching lines...) Expand all Loading... |
2331 | 2333 |
2332 __ bind(&done); | 2334 __ bind(&done); |
2333 context()->Plug(rax); | 2335 context()->Plug(rax); |
2334 } | 2336 } |
2335 | 2337 |
2336 | 2338 |
2337 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 2339 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
2338 Token::Value op, | 2340 Token::Value op, |
2339 OverwriteMode mode) { | 2341 OverwriteMode mode) { |
2340 __ Pop(rdx); | 2342 __ Pop(rdx); |
2341 BinaryOpICStub stub(isolate(), op, mode); | 2343 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code(); |
2342 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2344 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
2343 CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId()); | 2345 CallIC(code, expr->BinaryOperationFeedbackId()); |
2344 patch_site.EmitPatchInfo(); | 2346 patch_site.EmitPatchInfo(); |
2345 context()->Plug(rax); | 2347 context()->Plug(rax); |
2346 } | 2348 } |
2347 | 2349 |
2348 | 2350 |
2349 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2351 void FullCodeGenerator::EmitAssignment(Expression* expr) { |
2350 DCHECK(expr->IsValidReferenceExpression()); | 2352 DCHECK(expr->IsValidReferenceExpression()); |
2351 | 2353 |
2352 // Left-hand side can only be a property, a global or a (parameter or local) | 2354 // Left-hand side can only be a property, a global or a (parameter or local) |
2353 // slot. | 2355 // slot. |
(...skipping 23 matching lines...) Expand all Loading... |
2377 CallStoreIC(); | 2379 CallStoreIC(); |
2378 break; | 2380 break; |
2379 } | 2381 } |
2380 case KEYED_PROPERTY: { | 2382 case KEYED_PROPERTY: { |
2381 __ Push(rax); // Preserve value. | 2383 __ Push(rax); // Preserve value. |
2382 VisitForStackValue(prop->obj()); | 2384 VisitForStackValue(prop->obj()); |
2383 VisitForAccumulatorValue(prop->key()); | 2385 VisitForAccumulatorValue(prop->key()); |
2384 __ Move(StoreDescriptor::NameRegister(), rax); | 2386 __ Move(StoreDescriptor::NameRegister(), rax); |
2385 __ Pop(StoreDescriptor::ReceiverRegister()); | 2387 __ Pop(StoreDescriptor::ReceiverRegister()); |
2386 __ Pop(StoreDescriptor::ValueRegister()); // Restore value. | 2388 __ Pop(StoreDescriptor::ValueRegister()); // Restore value. |
2387 Handle<Code> ic = strict_mode() == SLOPPY | 2389 Handle<Code> ic = |
2388 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2390 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); |
2389 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | |
2390 CallIC(ic); | 2391 CallIC(ic); |
2391 break; | 2392 break; |
2392 } | 2393 } |
2393 } | 2394 } |
2394 context()->Plug(rax); | 2395 context()->Plug(rax); |
2395 } | 2396 } |
2396 | 2397 |
2397 | 2398 |
2398 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 2399 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
2399 Variable* var, MemOperand location) { | 2400 Variable* var, MemOperand location) { |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2491 | 2492 |
2492 | 2493 |
2493 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2494 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
2494 // Assignment to a property, using a keyed store IC. | 2495 // Assignment to a property, using a keyed store IC. |
2495 | 2496 |
2496 __ Pop(StoreDescriptor::NameRegister()); // Key. | 2497 __ Pop(StoreDescriptor::NameRegister()); // Key. |
2497 __ Pop(StoreDescriptor::ReceiverRegister()); | 2498 __ Pop(StoreDescriptor::ReceiverRegister()); |
2498 DCHECK(StoreDescriptor::ValueRegister().is(rax)); | 2499 DCHECK(StoreDescriptor::ValueRegister().is(rax)); |
2499 // Record source code position before IC call. | 2500 // Record source code position before IC call. |
2500 SetSourcePosition(expr->position()); | 2501 SetSourcePosition(expr->position()); |
2501 Handle<Code> ic = strict_mode() == SLOPPY | 2502 Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); |
2502 ? isolate()->builtins()->KeyedStoreIC_Initialize() | |
2503 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | |
2504 CallIC(ic, expr->AssignmentFeedbackId()); | 2503 CallIC(ic, expr->AssignmentFeedbackId()); |
2505 | 2504 |
2506 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2505 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2507 context()->Plug(rax); | 2506 context()->Plug(rax); |
2508 } | 2507 } |
2509 | 2508 |
2510 | 2509 |
2511 void FullCodeGenerator::VisitProperty(Property* expr) { | 2510 void FullCodeGenerator::VisitProperty(Property* expr) { |
2512 Comment cmnt(masm_, "[ Property"); | 2511 Comment cmnt(masm_, "[ Property"); |
2513 Expression* key = expr->key(); | 2512 Expression* key = expr->key(); |
(...skipping 1812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4326 } | 4325 } |
4327 } | 4326 } |
4328 | 4327 |
4329 // Record position before stub call. | 4328 // Record position before stub call. |
4330 SetSourcePosition(expr->position()); | 4329 SetSourcePosition(expr->position()); |
4331 | 4330 |
4332 // Call stub for +1/-1. | 4331 // Call stub for +1/-1. |
4333 __ bind(&stub_call); | 4332 __ bind(&stub_call); |
4334 __ movp(rdx, rax); | 4333 __ movp(rdx, rax); |
4335 __ Move(rax, Smi::FromInt(1)); | 4334 __ Move(rax, Smi::FromInt(1)); |
4336 BinaryOpICStub stub(isolate(), expr->binary_op(), NO_OVERWRITE); | 4335 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), expr->binary_op(), |
4337 CallIC(stub.GetCode(), expr->CountBinOpFeedbackId()); | 4336 NO_OVERWRITE).code(); |
| 4337 CallIC(code, expr->CountBinOpFeedbackId()); |
4338 patch_site.EmitPatchInfo(); | 4338 patch_site.EmitPatchInfo(); |
4339 __ bind(&done); | 4339 __ bind(&done); |
4340 | 4340 |
4341 // Store the value returned in rax. | 4341 // Store the value returned in rax. |
4342 switch (assign_type) { | 4342 switch (assign_type) { |
4343 case VARIABLE: | 4343 case VARIABLE: |
4344 if (expr->is_postfix()) { | 4344 if (expr->is_postfix()) { |
4345 // Perform the assignment as if via '='. | 4345 // Perform the assignment as if via '='. |
4346 { EffectContext context(this); | 4346 { EffectContext context(this); |
4347 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4347 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
(...skipping 25 matching lines...) Expand all Loading... |
4373 context()->PlugTOS(); | 4373 context()->PlugTOS(); |
4374 } | 4374 } |
4375 } else { | 4375 } else { |
4376 context()->Plug(rax); | 4376 context()->Plug(rax); |
4377 } | 4377 } |
4378 break; | 4378 break; |
4379 } | 4379 } |
4380 case KEYED_PROPERTY: { | 4380 case KEYED_PROPERTY: { |
4381 __ Pop(StoreDescriptor::NameRegister()); | 4381 __ Pop(StoreDescriptor::NameRegister()); |
4382 __ Pop(StoreDescriptor::ReceiverRegister()); | 4382 __ Pop(StoreDescriptor::ReceiverRegister()); |
4383 Handle<Code> ic = strict_mode() == SLOPPY | 4383 Handle<Code> ic = |
4384 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 4384 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); |
4385 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | |
4386 CallIC(ic, expr->CountStoreFeedbackId()); | 4385 CallIC(ic, expr->CountStoreFeedbackId()); |
4387 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4386 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4388 if (expr->is_postfix()) { | 4387 if (expr->is_postfix()) { |
4389 if (!context()->IsEffect()) { | 4388 if (!context()->IsEffect()) { |
4390 context()->PlugTOS(); | 4389 context()->PlugTOS(); |
4391 } | 4390 } |
4392 } else { | 4391 } else { |
4393 context()->Plug(rax); | 4392 context()->Plug(rax); |
4394 } | 4393 } |
4395 break; | 4394 break; |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4563 __ movp(rcx, rdx); | 4562 __ movp(rcx, rdx); |
4564 __ orp(rcx, rax); | 4563 __ orp(rcx, rax); |
4565 patch_site.EmitJumpIfNotSmi(rcx, &slow_case, Label::kNear); | 4564 patch_site.EmitJumpIfNotSmi(rcx, &slow_case, Label::kNear); |
4566 __ cmpp(rdx, rax); | 4565 __ cmpp(rdx, rax); |
4567 Split(cc, if_true, if_false, NULL); | 4566 Split(cc, if_true, if_false, NULL); |
4568 __ bind(&slow_case); | 4567 __ bind(&slow_case); |
4569 } | 4568 } |
4570 | 4569 |
4571 // Record position and call the compare IC. | 4570 // Record position and call the compare IC. |
4572 SetSourcePosition(expr->position()); | 4571 SetSourcePosition(expr->position()); |
4573 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); | 4572 Handle<Code> ic = CodeFactory::CompareIC(isolate(), op).code(); |
4574 CallIC(ic, expr->CompareOperationFeedbackId()); | 4573 CallIC(ic, expr->CompareOperationFeedbackId()); |
4575 patch_site.EmitPatchInfo(); | 4574 patch_site.EmitPatchInfo(); |
4576 | 4575 |
4577 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4576 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
4578 __ testp(rax, rax); | 4577 __ testp(rax, rax); |
4579 Split(cc, if_true, if_false, fall_through); | 4578 Split(cc, if_true, if_false, fall_through); |
4580 } | 4579 } |
4581 } | 4580 } |
4582 | 4581 |
4583 // Convert the result of the comparison into one expected for this | 4582 // Convert the result of the comparison into one expected for this |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4834 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4833 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
4835 Assembler::target_address_at(call_target_address, | 4834 Assembler::target_address_at(call_target_address, |
4836 unoptimized_code)); | 4835 unoptimized_code)); |
4837 return OSR_AFTER_STACK_CHECK; | 4836 return OSR_AFTER_STACK_CHECK; |
4838 } | 4837 } |
4839 | 4838 |
4840 | 4839 |
4841 } } // namespace v8::internal | 4840 } } // namespace v8::internal |
4842 | 4841 |
4843 #endif // V8_TARGET_ARCH_X64 | 4842 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |