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-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 961 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
980 | 981 |
981 __ cmp(edx, eax); | 982 __ cmp(edx, eax); |
982 __ j(not_equal, &next_test); | 983 __ j(not_equal, &next_test); |
983 __ Drop(1); // Switch value is no longer needed. | 984 __ Drop(1); // Switch value is no longer needed. |
984 __ jmp(clause->body_target()); | 985 __ jmp(clause->body_target()); |
985 __ bind(&slow_case); | 986 __ bind(&slow_case); |
986 } | 987 } |
987 | 988 |
988 // Record position before stub call for type feedback. | 989 // Record position before stub call for type feedback. |
989 SetSourcePosition(clause->position()); | 990 SetSourcePosition(clause->position()); |
990 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); | 991 Handle<Code> ic = |
| 992 CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code(); |
991 CallIC(ic, clause->CompareId()); | 993 CallIC(ic, clause->CompareId()); |
992 patch_site.EmitPatchInfo(); | 994 patch_site.EmitPatchInfo(); |
993 | 995 |
994 Label skip; | 996 Label skip; |
995 __ jmp(&skip, Label::kNear); | 997 __ jmp(&skip, Label::kNear); |
996 PrepareForBailout(clause, TOS_REG); | 998 PrepareForBailout(clause, TOS_REG); |
997 __ cmp(eax, isolate()->factory()->true_value()); | 999 __ cmp(eax, isolate()->factory()->true_value()); |
998 __ j(not_equal, &next_test); | 1000 __ j(not_equal, &next_test); |
999 __ Drop(1); | 1001 __ Drop(1); |
1000 __ jmp(clause->body_target()); | 1002 __ jmp(clause->body_target()); |
(...skipping 1016 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2017 __ push(Operand(esp, 2 * kPointerSize)); // iter | 2019 __ push(Operand(esp, 2 * kPointerSize)); // iter |
2018 __ push(eax); // received | 2020 __ push(eax); // received |
2019 | 2021 |
2020 // result = receiver[f](arg); | 2022 // result = receiver[f](arg); |
2021 __ bind(&l_call); | 2023 __ bind(&l_call); |
2022 __ mov(load_receiver, Operand(esp, kPointerSize)); | 2024 __ mov(load_receiver, Operand(esp, kPointerSize)); |
2023 if (FLAG_vector_ics) { | 2025 if (FLAG_vector_ics) { |
2024 __ mov(VectorLoadICDescriptor::SlotRegister(), | 2026 __ mov(VectorLoadICDescriptor::SlotRegister(), |
2025 Immediate(Smi::FromInt(expr->KeyedLoadFeedbackSlot()))); | 2027 Immediate(Smi::FromInt(expr->KeyedLoadFeedbackSlot()))); |
2026 } | 2028 } |
2027 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2029 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); |
2028 CallIC(ic, TypeFeedbackId::None()); | 2030 CallIC(ic, TypeFeedbackId::None()); |
2029 __ mov(edi, eax); | 2031 __ mov(edi, eax); |
2030 __ mov(Operand(esp, 2 * kPointerSize), edi); | 2032 __ mov(Operand(esp, 2 * kPointerSize), edi); |
2031 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); | 2033 CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); |
2032 __ CallStub(&stub); | 2034 __ CallStub(&stub); |
2033 | 2035 |
2034 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2036 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
2035 __ Drop(1); // The function is still on the stack; drop it. | 2037 __ Drop(1); // The function is still on the stack; drop it. |
2036 | 2038 |
2037 // if (!result.done) goto l_try; | 2039 // if (!result.done) goto l_try; |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2223 Immediate(Smi::FromInt(prop->PropertyFeedbackSlot()))); | 2225 Immediate(Smi::FromInt(prop->PropertyFeedbackSlot()))); |
2224 CallLoadIC(NOT_CONTEXTUAL); | 2226 CallLoadIC(NOT_CONTEXTUAL); |
2225 } else { | 2227 } else { |
2226 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); | 2228 CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); |
2227 } | 2229 } |
2228 } | 2230 } |
2229 | 2231 |
2230 | 2232 |
2231 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2233 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
2232 SetSourcePosition(prop->position()); | 2234 SetSourcePosition(prop->position()); |
2233 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2235 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code(); |
2234 if (FLAG_vector_ics) { | 2236 if (FLAG_vector_ics) { |
2235 __ mov(VectorLoadICDescriptor::SlotRegister(), | 2237 __ mov(VectorLoadICDescriptor::SlotRegister(), |
2236 Immediate(Smi::FromInt(prop->PropertyFeedbackSlot()))); | 2238 Immediate(Smi::FromInt(prop->PropertyFeedbackSlot()))); |
2237 CallIC(ic); | 2239 CallIC(ic); |
2238 } else { | 2240 } else { |
2239 CallIC(ic, prop->PropertyFeedbackId()); | 2241 CallIC(ic, prop->PropertyFeedbackId()); |
2240 } | 2242 } |
2241 } | 2243 } |
2242 | 2244 |
2243 | 2245 |
2244 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2246 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
2245 Token::Value op, | 2247 Token::Value op, |
2246 OverwriteMode mode, | 2248 OverwriteMode mode, |
2247 Expression* left, | 2249 Expression* left, |
2248 Expression* right) { | 2250 Expression* right) { |
2249 // Do combined smi check of the operands. Left operand is on the | 2251 // Do combined smi check of the operands. Left operand is on the |
2250 // stack. Right operand is in eax. | 2252 // stack. Right operand is in eax. |
2251 Label smi_case, done, stub_call; | 2253 Label smi_case, done, stub_call; |
2252 __ pop(edx); | 2254 __ pop(edx); |
2253 __ mov(ecx, eax); | 2255 __ mov(ecx, eax); |
2254 __ or_(eax, edx); | 2256 __ or_(eax, edx); |
2255 JumpPatchSite patch_site(masm_); | 2257 JumpPatchSite patch_site(masm_); |
2256 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); | 2258 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); |
2257 | 2259 |
2258 __ bind(&stub_call); | 2260 __ bind(&stub_call); |
2259 __ mov(eax, ecx); | 2261 __ mov(eax, ecx); |
2260 BinaryOpICStub stub(isolate(), op, mode); | 2262 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code(); |
2261 CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId()); | 2263 CallIC(code, expr->BinaryOperationFeedbackId()); |
2262 patch_site.EmitPatchInfo(); | 2264 patch_site.EmitPatchInfo(); |
2263 __ jmp(&done, Label::kNear); | 2265 __ jmp(&done, Label::kNear); |
2264 | 2266 |
2265 // Smi case. | 2267 // Smi case. |
2266 __ bind(&smi_case); | 2268 __ bind(&smi_case); |
2267 __ mov(eax, edx); // Copy left operand in case of a stub call. | 2269 __ mov(eax, edx); // Copy left operand in case of a stub call. |
2268 | 2270 |
2269 switch (op) { | 2271 switch (op) { |
2270 case Token::SAR: | 2272 case Token::SAR: |
2271 __ SmiUntag(ecx); | 2273 __ SmiUntag(ecx); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2333 | 2335 |
2334 __ bind(&done); | 2336 __ bind(&done); |
2335 context()->Plug(eax); | 2337 context()->Plug(eax); |
2336 } | 2338 } |
2337 | 2339 |
2338 | 2340 |
2339 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 2341 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
2340 Token::Value op, | 2342 Token::Value op, |
2341 OverwriteMode mode) { | 2343 OverwriteMode mode) { |
2342 __ pop(edx); | 2344 __ pop(edx); |
2343 BinaryOpICStub stub(isolate(), op, mode); | 2345 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code(); |
2344 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2346 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
2345 CallIC(stub.GetCode(), expr->BinaryOperationFeedbackId()); | 2347 CallIC(code, expr->BinaryOperationFeedbackId()); |
2346 patch_site.EmitPatchInfo(); | 2348 patch_site.EmitPatchInfo(); |
2347 context()->Plug(eax); | 2349 context()->Plug(eax); |
2348 } | 2350 } |
2349 | 2351 |
2350 | 2352 |
2351 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2353 void FullCodeGenerator::EmitAssignment(Expression* expr) { |
2352 DCHECK(expr->IsValidReferenceExpression()); | 2354 DCHECK(expr->IsValidReferenceExpression()); |
2353 | 2355 |
2354 // Left-hand side can only be a property, a global or a (parameter or local) | 2356 // Left-hand side can only be a property, a global or a (parameter or local) |
2355 // slot. | 2357 // slot. |
(...skipping 23 matching lines...) Expand all Loading... |
2379 CallStoreIC(); | 2381 CallStoreIC(); |
2380 break; | 2382 break; |
2381 } | 2383 } |
2382 case KEYED_PROPERTY: { | 2384 case KEYED_PROPERTY: { |
2383 __ push(eax); // Preserve value. | 2385 __ push(eax); // Preserve value. |
2384 VisitForStackValue(prop->obj()); | 2386 VisitForStackValue(prop->obj()); |
2385 VisitForAccumulatorValue(prop->key()); | 2387 VisitForAccumulatorValue(prop->key()); |
2386 __ Move(StoreDescriptor::NameRegister(), eax); | 2388 __ Move(StoreDescriptor::NameRegister(), eax); |
2387 __ pop(StoreDescriptor::ReceiverRegister()); // Receiver. | 2389 __ pop(StoreDescriptor::ReceiverRegister()); // Receiver. |
2388 __ pop(StoreDescriptor::ValueRegister()); // Restore value. | 2390 __ pop(StoreDescriptor::ValueRegister()); // Restore value. |
2389 Handle<Code> ic = strict_mode() == SLOPPY | 2391 Handle<Code> ic = |
2390 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2392 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); |
2391 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | |
2392 CallIC(ic); | 2393 CallIC(ic); |
2393 break; | 2394 break; |
2394 } | 2395 } |
2395 } | 2396 } |
2396 context()->Plug(eax); | 2397 context()->Plug(eax); |
2397 } | 2398 } |
2398 | 2399 |
2399 | 2400 |
2400 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 2401 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
2401 Variable* var, MemOperand location) { | 2402 Variable* var, MemOperand location) { |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2498 // Assignment to a property, using a keyed store IC. | 2499 // Assignment to a property, using a keyed store IC. |
2499 // eax : value | 2500 // eax : value |
2500 // esp[0] : key | 2501 // esp[0] : key |
2501 // esp[kPointerSize] : receiver | 2502 // esp[kPointerSize] : receiver |
2502 | 2503 |
2503 __ pop(StoreDescriptor::NameRegister()); // Key. | 2504 __ pop(StoreDescriptor::NameRegister()); // Key. |
2504 __ pop(StoreDescriptor::ReceiverRegister()); | 2505 __ pop(StoreDescriptor::ReceiverRegister()); |
2505 DCHECK(StoreDescriptor::ValueRegister().is(eax)); | 2506 DCHECK(StoreDescriptor::ValueRegister().is(eax)); |
2506 // Record source code position before IC call. | 2507 // Record source code position before IC call. |
2507 SetSourcePosition(expr->position()); | 2508 SetSourcePosition(expr->position()); |
2508 Handle<Code> ic = strict_mode() == SLOPPY | 2509 Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); |
2509 ? isolate()->builtins()->KeyedStoreIC_Initialize() | |
2510 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | |
2511 CallIC(ic, expr->AssignmentFeedbackId()); | 2510 CallIC(ic, expr->AssignmentFeedbackId()); |
2512 | 2511 |
2513 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2512 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2514 context()->Plug(eax); | 2513 context()->Plug(eax); |
2515 } | 2514 } |
2516 | 2515 |
2517 | 2516 |
2518 void FullCodeGenerator::VisitProperty(Property* expr) { | 2517 void FullCodeGenerator::VisitProperty(Property* expr) { |
2519 Comment cmnt(masm_, "[ Property"); | 2518 Comment cmnt(masm_, "[ Property"); |
2520 Expression* key = expr->key(); | 2519 Expression* key = expr->key(); |
(...skipping 1797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4318 } | 4317 } |
4319 } | 4318 } |
4320 | 4319 |
4321 // Record position before stub call. | 4320 // Record position before stub call. |
4322 SetSourcePosition(expr->position()); | 4321 SetSourcePosition(expr->position()); |
4323 | 4322 |
4324 // Call stub for +1/-1. | 4323 // Call stub for +1/-1. |
4325 __ bind(&stub_call); | 4324 __ bind(&stub_call); |
4326 __ mov(edx, eax); | 4325 __ mov(edx, eax); |
4327 __ mov(eax, Immediate(Smi::FromInt(1))); | 4326 __ mov(eax, Immediate(Smi::FromInt(1))); |
4328 BinaryOpICStub stub(isolate(), expr->binary_op(), NO_OVERWRITE); | 4327 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), expr->binary_op(), |
4329 CallIC(stub.GetCode(), expr->CountBinOpFeedbackId()); | 4328 NO_OVERWRITE).code(); |
| 4329 CallIC(code, expr->CountBinOpFeedbackId()); |
4330 patch_site.EmitPatchInfo(); | 4330 patch_site.EmitPatchInfo(); |
4331 __ bind(&done); | 4331 __ bind(&done); |
4332 | 4332 |
4333 // Store the value returned in eax. | 4333 // Store the value returned in eax. |
4334 switch (assign_type) { | 4334 switch (assign_type) { |
4335 case VARIABLE: | 4335 case VARIABLE: |
4336 if (expr->is_postfix()) { | 4336 if (expr->is_postfix()) { |
4337 // Perform the assignment as if via '='. | 4337 // Perform the assignment as if via '='. |
4338 { EffectContext context(this); | 4338 { EffectContext context(this); |
4339 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4339 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
(...skipping 25 matching lines...) Expand all Loading... |
4365 context()->PlugTOS(); | 4365 context()->PlugTOS(); |
4366 } | 4366 } |
4367 } else { | 4367 } else { |
4368 context()->Plug(eax); | 4368 context()->Plug(eax); |
4369 } | 4369 } |
4370 break; | 4370 break; |
4371 } | 4371 } |
4372 case KEYED_PROPERTY: { | 4372 case KEYED_PROPERTY: { |
4373 __ pop(StoreDescriptor::NameRegister()); | 4373 __ pop(StoreDescriptor::NameRegister()); |
4374 __ pop(StoreDescriptor::ReceiverRegister()); | 4374 __ pop(StoreDescriptor::ReceiverRegister()); |
4375 Handle<Code> ic = strict_mode() == SLOPPY | 4375 Handle<Code> ic = |
4376 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 4376 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); |
4377 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | |
4378 CallIC(ic, expr->CountStoreFeedbackId()); | 4377 CallIC(ic, expr->CountStoreFeedbackId()); |
4379 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4378 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4380 if (expr->is_postfix()) { | 4379 if (expr->is_postfix()) { |
4381 // Result is on the stack | 4380 // Result is on the stack |
4382 if (!context()->IsEffect()) { | 4381 if (!context()->IsEffect()) { |
4383 context()->PlugTOS(); | 4382 context()->PlugTOS(); |
4384 } | 4383 } |
4385 } else { | 4384 } else { |
4386 context()->Plug(eax); | 4385 context()->Plug(eax); |
4387 } | 4386 } |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4556 __ mov(ecx, edx); | 4555 __ mov(ecx, edx); |
4557 __ or_(ecx, eax); | 4556 __ or_(ecx, eax); |
4558 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); | 4557 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); |
4559 __ cmp(edx, eax); | 4558 __ cmp(edx, eax); |
4560 Split(cc, if_true, if_false, NULL); | 4559 Split(cc, if_true, if_false, NULL); |
4561 __ bind(&slow_case); | 4560 __ bind(&slow_case); |
4562 } | 4561 } |
4563 | 4562 |
4564 // Record position and call the compare IC. | 4563 // Record position and call the compare IC. |
4565 SetSourcePosition(expr->position()); | 4564 SetSourcePosition(expr->position()); |
4566 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); | 4565 Handle<Code> ic = CodeFactory::CompareIC(isolate(), op).code(); |
4567 CallIC(ic, expr->CompareOperationFeedbackId()); | 4566 CallIC(ic, expr->CompareOperationFeedbackId()); |
4568 patch_site.EmitPatchInfo(); | 4567 patch_site.EmitPatchInfo(); |
4569 | 4568 |
4570 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 4569 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
4571 __ test(eax, eax); | 4570 __ test(eax, eax); |
4572 Split(cc, if_true, if_false, fall_through); | 4571 Split(cc, if_true, if_false, fall_through); |
4573 } | 4572 } |
4574 } | 4573 } |
4575 | 4574 |
4576 // Convert the result of the comparison into one expected for this | 4575 // Convert the result of the comparison into one expected for this |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4824 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4823 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
4825 Assembler::target_address_at(call_target_address, | 4824 Assembler::target_address_at(call_target_address, |
4826 unoptimized_code)); | 4825 unoptimized_code)); |
4827 return OSR_AFTER_STACK_CHECK; | 4826 return OSR_AFTER_STACK_CHECK; |
4828 } | 4827 } |
4829 | 4828 |
4830 | 4829 |
4831 } } // namespace v8::internal | 4830 } } // namespace v8::internal |
4832 | 4831 |
4833 #endif // V8_TARGET_ARCH_IA32 | 4832 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |