| 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 |