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_X87 | 7 #if V8_TARGET_ARCH_X87 |
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 958 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
977 | 978 |
978 __ cmp(edx, eax); | 979 __ cmp(edx, eax); |
979 __ j(not_equal, &next_test); | 980 __ j(not_equal, &next_test); |
980 __ Drop(1); // Switch value is no longer needed. | 981 __ Drop(1); // Switch value is no longer needed. |
981 __ jmp(clause->body_target()); | 982 __ jmp(clause->body_target()); |
982 __ bind(&slow_case); | 983 __ bind(&slow_case); |
983 } | 984 } |
984 | 985 |
985 // Record position before stub call for type feedback. | 986 // Record position before stub call for type feedback. |
986 SetSourcePosition(clause->position()); | 987 SetSourcePosition(clause->position()); |
987 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); | 988 Handle<Code> ic = |
| 989 CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code(); |
988 CallIC(ic, clause->CompareId()); | 990 CallIC(ic, clause->CompareId()); |
989 patch_site.EmitPatchInfo(); | 991 patch_site.EmitPatchInfo(); |
990 | 992 |
991 Label skip; | 993 Label skip; |
992 __ jmp(&skip, Label::kNear); | 994 __ jmp(&skip, Label::kNear); |
993 PrepareForBailout(clause, TOS_REG); | 995 PrepareForBailout(clause, TOS_REG); |
994 __ cmp(eax, isolate()->factory()->true_value()); | 996 __ cmp(eax, isolate()->factory()->true_value()); |
995 __ j(not_equal, &next_test); | 997 __ j(not_equal, &next_test); |
996 __ Drop(1); | 998 __ Drop(1); |
997 __ jmp(clause->body_target()); | 999 __ jmp(clause->body_target()); |
(...skipping 1013 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2011 __ push(Operand(esp, 2 * kPointerSize)); // iter | 2013 __ push(Operand(esp, 2 * kPointerSize)); // iter |
2012 __ push(eax); // received | 2014 __ push(eax); // received |
2013 | 2015 |
2014 // result = receiver[f](arg); | 2016 // result = receiver[f](arg); |
2015 __ bind(&l_call); | 2017 __ bind(&l_call); |
2016 __ mov(load_receiver, Operand(esp, kPointerSize)); | 2018 __ mov(load_receiver, Operand(esp, kPointerSize)); |
2017 if (FLAG_vector_ics) { | 2019 if (FLAG_vector_ics) { |
2018 __ mov(VectorLoadICDescriptor::SlotRegister(), | 2020 __ mov(VectorLoadICDescriptor::SlotRegister(), |
2019 Immediate(Smi::FromInt(expr->KeyedLoadFeedbackSlot()))); | 2021 Immediate(Smi::FromInt(expr->KeyedLoadFeedbackSlot()))); |
2020 } | 2022 } |
2021 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2023 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); |
2022 CallIC(ic, TypeFeedbackId::None()); | 2024 CallIC(ic, TypeFeedbackId::None()); |
2023 __ mov(edi, eax); | 2025 __ mov(edi, eax); |
2024 __ mov(Operand(esp, 2 * kPointerSize), edi); | 2026 __ mov(Operand(esp, 2 * kPointerSize), edi); |
2025 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); | 2027 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); |
2026 __ CallStub(&stub); | 2028 __ CallStub(&stub); |
2027 | 2029 |
2028 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2030 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
2029 __ Drop(1); // The function is still on the stack; drop it. | 2031 __ Drop(1); // The function is still on the stack; drop it. |
2030 | 2032 |
2031 // if (!result.done) goto l_try; | 2033 // if (!result.done) goto l_try; |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2217 Immediate(Smi::FromInt(prop->PropertyFeedbackSlot()))); | 2219 Immediate(Smi::FromInt(prop->PropertyFeedbackSlot()))); |
2218 CallLoadIC(NOT_CONTEXTUAL); | 2220 CallLoadIC(NOT_CONTEXTUAL); |
2219 } else { | 2221 } else { |
2220 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); | 2222 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
2221 } | 2223 } |
2222 } | 2224 } |
2223 | 2225 |
2224 | 2226 |
2225 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2227 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
2226 SetSourcePosition(prop->position()); | 2228 SetSourcePosition(prop->position()); |
2227 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2229 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); |
2228 if (FLAG_vector_ics) { | 2230 if (FLAG_vector_ics) { |
2229 __ mov(VectorLoadICDescriptor::SlotRegister(), | 2231 __ mov(VectorLoadICDescriptor::SlotRegister(), |
2230 Immediate(Smi::FromInt(prop->PropertyFeedbackSlot()))); | 2232 Immediate(Smi::FromInt(prop->PropertyFeedbackSlot()))); |
2231 CallIC(ic); | 2233 CallIC(ic); |
2232 } else { | 2234 } else { |
2233 CallIC(ic, prop->PropertyFeedbackId()); | 2235 CallIC(ic, prop->PropertyFeedbackId()); |
2234 } | 2236 } |
2235 } | 2237 } |
2236 | 2238 |
2237 | 2239 |
2238 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2240 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
2239 Token::Value op, | 2241 Token::Value op, |
2240 OverwriteMode mode, | 2242 OverwriteMode mode, |
2241 Expression* left, | 2243 Expression* left, |
2242 Expression* right) { | 2244 Expression* right) { |
2243 // Do combined smi check of the operands. Left operand is on the | 2245 // Do combined smi check of the operands. Left operand is on the |
2244 // stack. Right operand is in eax. | 2246 // stack. Right operand is in eax. |
2245 Label smi_case, done, stub_call; | 2247 Label smi_case, done, stub_call; |
2246 __ pop(edx); | 2248 __ pop(edx); |
2247 __ mov(ecx, eax); | 2249 __ mov(ecx, eax); |
2248 __ or_(eax, edx); | 2250 __ or_(eax, edx); |
2249 JumpPatchSite patch_site(masm_); | 2251 JumpPatchSite patch_site(masm_); |
2250 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); | 2252 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); |
2251 | 2253 |
2252 __ bind(&stub_call); | 2254 __ bind(&stub_call); |
2253 __ mov(eax, ecx); | 2255 __ mov(eax, ecx); |
2254 BinaryOpICStub stub(isolate(), op, mode); | 2256 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code(); |
2255 CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId()); | 2257 CallIC(code, expr->BinaryOperationFeedbackId()); |
2256 patch_site.EmitPatchInfo(); | 2258 patch_site.EmitPatchInfo(); |
2257 __ jmp(&done, Label::kNear); | 2259 __ jmp(&done, Label::kNear); |
2258 | 2260 |
2259 // Smi case. | 2261 // Smi case. |
2260 __ bind(&smi_case); | 2262 __ bind(&smi_case); |
2261 __ mov(eax, edx); // Copy left operand in case of a stub call. | 2263 __ mov(eax, edx); // Copy left operand in case of a stub call. |
2262 | 2264 |
2263 switch (op) { | 2265 switch (op) { |
2264 case Token::SAR: | 2266 case Token::SAR: |
2265 __ SmiUntag(ecx); | 2267 __ SmiUntag(ecx); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2327 | 2329 |
2328 __ bind(&done); | 2330 __ bind(&done); |
2329 context()->Plug(eax); | 2331 context()->Plug(eax); |
2330 } | 2332 } |
2331 | 2333 |
2332 | 2334 |
2333 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 2335 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
2334 Token::Value op, | 2336 Token::Value op, |
2335 OverwriteMode mode) { | 2337 OverwriteMode mode) { |
2336 __ pop(edx); | 2338 __ pop(edx); |
2337 BinaryOpICStub stub(isolate(), op, mode); | 2339 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code(); |
2338 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2340 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
2339 CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId()); | 2341 CallIC(code, expr->BinaryOperationFeedbackId()); |
2340 patch_site.EmitPatchInfo(); | 2342 patch_site.EmitPatchInfo(); |
2341 context()->Plug(eax); | 2343 context()->Plug(eax); |
2342 } | 2344 } |
2343 | 2345 |
2344 | 2346 |
2345 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2347 void FullCodeGenerator::EmitAssignment(Expression* expr) { |
2346 DCHECK(expr->IsValidReferenceExpression()); | 2348 DCHECK(expr->IsValidReferenceExpression()); |
2347 | 2349 |
2348 // Left-hand side can only be a property, a global or a (parameter or local) | 2350 // Left-hand side can only be a property, a global or a (parameter or local) |
2349 // slot. | 2351 // slot. |
(...skipping 23 matching lines...) Expand all Loading... |
2373 CallStoreIC(); | 2375 CallStoreIC(); |
2374 break; | 2376 break; |
2375 } | 2377 } |
2376 case KEYED_PROPERTY: { | 2378 case KEYED_PROPERTY: { |
2377 __ push(eax); // Preserve value. | 2379 __ push(eax); // Preserve value. |
2378 VisitForStackValue(prop->obj()); | 2380 VisitForStackValue(prop->obj()); |
2379 VisitForAccumulatorValue(prop->key()); | 2381 VisitForAccumulatorValue(prop->key()); |
2380 __ Move(StoreDescriptor::NameRegister(), eax); | 2382 __ Move(StoreDescriptor::NameRegister(), eax); |
2381 __ pop(StoreDescriptor::ReceiverRegister()); // Receiver. | 2383 __ pop(StoreDescriptor::ReceiverRegister()); // Receiver. |
2382 __ pop(StoreDescriptor::ValueRegister()); // Restore value. | 2384 __ pop(StoreDescriptor::ValueRegister()); // Restore value. |
2383 Handle<Code> ic = strict_mode() == SLOPPY | 2385 Handle<Code> ic = |
2384 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2386 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); |
2385 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | |
2386 CallIC(ic); | 2387 CallIC(ic); |
2387 break; | 2388 break; |
2388 } | 2389 } |
2389 } | 2390 } |
2390 context()->Plug(eax); | 2391 context()->Plug(eax); |
2391 } | 2392 } |
2392 | 2393 |
2393 | 2394 |
2394 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 2395 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
2395 Variable* var, MemOperand location) { | 2396 Variable* var, MemOperand location) { |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2492 // Assignment to a property, using a keyed store IC. | 2493 // Assignment to a property, using a keyed store IC. |
2493 // eax : value | 2494 // eax : value |
2494 // esp[0] : key | 2495 // esp[0] : key |
2495 // esp[kPointerSize] : receiver | 2496 // esp[kPointerSize] : receiver |
2496 | 2497 |
2497 __ pop(StoreDescriptor::NameRegister()); // Key. | 2498 __ pop(StoreDescriptor::NameRegister()); // Key. |
2498 __ pop(StoreDescriptor::ReceiverRegister()); | 2499 __ pop(StoreDescriptor::ReceiverRegister()); |
2499 DCHECK(StoreDescriptor::ValueRegister().is(eax)); | 2500 DCHECK(StoreDescriptor::ValueRegister().is(eax)); |
2500 // Record source code position before IC call. | 2501 // Record source code position before IC call. |
2501 SetSourcePosition(expr->position()); | 2502 SetSourcePosition(expr->position()); |
2502 Handle<Code> ic = strict_mode() == SLOPPY | 2503 Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); |
2503 ? isolate()->builtins()->KeyedStoreIC_Initialize() | |
2504 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | |
2505 CallIC(ic, expr->AssignmentFeedbackId()); | 2504 CallIC(ic, expr->AssignmentFeedbackId()); |
2506 | 2505 |
2507 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2506 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2508 context()->Plug(eax); | 2507 context()->Plug(eax); |
2509 } | 2508 } |
2510 | 2509 |
2511 | 2510 |
2512 void FullCodeGenerator::VisitProperty(Property* expr) { | 2511 void FullCodeGenerator::VisitProperty(Property* expr) { |
2513 Comment cmnt(masm_, "[ Property"); | 2512 Comment cmnt(masm_, "[ Property"); |
2514 Expression* key = expr->key(); | 2513 Expression* key = expr->key(); |
(...skipping 1796 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4311 } | 4310 } |
4312 } | 4311 } |
4313 | 4312 |
4314 // Record position before stub call. | 4313 // Record position before stub call. |
4315 SetSourcePosition(expr->position()); | 4314 SetSourcePosition(expr->position()); |
4316 | 4315 |
4317 // Call stub for +1/-1. | 4316 // Call stub for +1/-1. |
4318 __ bind(&stub_call); | 4317 __ bind(&stub_call); |
4319 __ mov(edx, eax); | 4318 __ mov(edx, eax); |
4320 __ mov(eax, Immediate(Smi::FromInt(1))); | 4319 __ mov(eax, Immediate(Smi::FromInt(1))); |
4321 BinaryOpICStub stub(isolate(), expr->binary_op(), NO_OVERWRITE); | 4320 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), expr->binary_op(), |
4322 CallIC(stub.GetCode(), expr->CountBinOpFeedbackId()); | 4321 NO_OVERWRITE).code(); |
| 4322 CallIC(code, expr->CountBinOpFeedbackId()); |
4323 patch_site.EmitPatchInfo(); | 4323 patch_site.EmitPatchInfo(); |
4324 __ bind(&done); | 4324 __ bind(&done); |
4325 | 4325 |
4326 // Store the value returned in eax. | 4326 // Store the value returned in eax. |
4327 switch (assign_type) { | 4327 switch (assign_type) { |
4328 case VARIABLE: | 4328 case VARIABLE: |
4329 if (expr->is_postfix()) { | 4329 if (expr->is_postfix()) { |
4330 // Perform the assignment as if via '='. | 4330 // Perform the assignment as if via '='. |
4331 { EffectContext context(this); | 4331 { EffectContext context(this); |
4332 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4332 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
(...skipping 25 matching lines...) Expand all Loading... |
4358 context()->PlugTOS(); | 4358 context()->PlugTOS(); |
4359 } | 4359 } |
4360 } else { | 4360 } else { |
4361 context()->Plug(eax); | 4361 context()->Plug(eax); |
4362 } | 4362 } |
4363 break; | 4363 break; |
4364 } | 4364 } |
4365 case KEYED_PROPERTY: { | 4365 case KEYED_PROPERTY: { |
4366 __ pop(StoreDescriptor::NameRegister()); | 4366 __ pop(StoreDescriptor::NameRegister()); |
4367 __ pop(StoreDescriptor::ReceiverRegister()); | 4367 __ pop(StoreDescriptor::ReceiverRegister()); |
4368 Handle<Code> ic = strict_mode() == SLOPPY | 4368 Handle<Code> ic = |
4369 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 4369 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); |
4370 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | |
4371 CallIC(ic, expr->CountStoreFeedbackId()); | 4370 CallIC(ic, expr->CountStoreFeedbackId()); |
4372 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4371 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4373 if (expr->is_postfix()) { | 4372 if (expr->is_postfix()) { |
4374 // Result is on the stack | 4373 // Result is on the stack |
4375 if (!context()->IsEffect()) { | 4374 if (!context()->IsEffect()) { |
4376 context()->PlugTOS(); | 4375 context()->PlugTOS(); |
4377 } | 4376 } |
4378 } else { | 4377 } else { |
4379 context()->Plug(eax); | 4378 context()->Plug(eax); |
4380 } | 4379 } |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4549 __ mov(ecx, edx); | 4548 __ mov(ecx, edx); |
4550 __ or_(ecx, eax); | 4549 __ or_(ecx, eax); |
4551 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); | 4550 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); |
4552 __ cmp(edx, eax); | 4551 __ cmp(edx, eax); |
4553 Split(cc, if_true, if_false, NULL); | 4552 Split(cc, if_true, if_false, NULL); |
4554 __ bind(&slow_case); | 4553 __ bind(&slow_case); |
4555 } | 4554 } |
4556 | 4555 |
4557 // Record position and call the compare IC. | 4556 // Record position and call the compare IC. |
4558 SetSourcePosition(expr->position()); | 4557 SetSourcePosition(expr->position()); |
4559 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); | 4558 Handle<Code> ic = CodeFactory::CompareIC(isolate(), op).code(); |
4560 CallIC(ic, expr->CompareOperationFeedbackId()); | 4559 CallIC(ic, expr->CompareOperationFeedbackId()); |
4561 patch_site.EmitPatchInfo(); | 4560 patch_site.EmitPatchInfo(); |
4562 | 4561 |
4563 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4562 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
4564 __ test(eax, eax); | 4563 __ test(eax, eax); |
4565 Split(cc, if_true, if_false, fall_through); | 4564 Split(cc, if_true, if_false, fall_through); |
4566 } | 4565 } |
4567 } | 4566 } |
4568 | 4567 |
4569 // Convert the result of the comparison into one expected for this | 4568 // Convert the result of the comparison into one expected for this |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4817 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4816 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
4818 Assembler::target_address_at(call_target_address, | 4817 Assembler::target_address_at(call_target_address, |
4819 unoptimized_code)); | 4818 unoptimized_code)); |
4820 return OSR_AFTER_STACK_CHECK; | 4819 return OSR_AFTER_STACK_CHECK; |
4821 } | 4820 } |
4822 | 4821 |
4823 | 4822 |
4824 } } // namespace v8::internal | 4823 } } // namespace v8::internal |
4825 | 4824 |
4826 #endif // V8_TARGET_ARCH_X87 | 4825 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |