Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(209)

Side by Side Diff: src/ia32/full-codegen-ia32.cc

Issue 96083005: Remove Reloc::Mode CODE_TARGET_CONTEXT (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Complete for ia32. Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 if (false_label_ != fall_through_) __ jmp(false_label_); 631 if (false_label_ != fall_through_) __ jmp(false_label_);
632 } 632 }
633 } 633 }
634 634
635 635
636 void FullCodeGenerator::DoTest(Expression* condition, 636 void FullCodeGenerator::DoTest(Expression* condition,
637 Label* if_true, 637 Label* if_true,
638 Label* if_false, 638 Label* if_false,
639 Label* fall_through) { 639 Label* fall_through) {
640 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate()); 640 Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate());
641 CallIC(ic, RelocInfo::CODE_TARGET, condition->test_id()); 641 CallIC(ic, NOT_CONTEXTUAL, condition->test_id());
642 __ test(result_register(), result_register()); 642 __ test(result_register(), result_register());
643 // The stub returns nonzero for true. 643 // The stub returns nonzero for true.
644 Split(not_zero, if_true, if_false, fall_through); 644 Split(not_zero, if_true, if_false, fall_through);
645 } 645 }
646 646
647 647
648 void FullCodeGenerator::Split(Condition cc, 648 void FullCodeGenerator::Split(Condition cc,
649 Label* if_true, 649 Label* if_true,
650 Label* if_false, 650 Label* if_false,
651 Label* fall_through) { 651 Label* fall_through) {
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
982 __ cmp(edx, eax); 982 __ cmp(edx, eax);
983 __ j(not_equal, &next_test); 983 __ j(not_equal, &next_test);
984 __ Drop(1); // Switch value is no longer needed. 984 __ Drop(1); // Switch value is no longer needed.
985 __ jmp(clause->body_target()); 985 __ jmp(clause->body_target());
986 __ bind(&slow_case); 986 __ bind(&slow_case);
987 } 987 }
988 988
989 // Record position before stub call for type feedback. 989 // Record position before stub call for type feedback.
990 SetSourcePosition(clause->position()); 990 SetSourcePosition(clause->position());
991 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT); 991 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), Token::EQ_STRICT);
992 CallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId()); 992 CallIC(ic, NOT_CONTEXTUAL, clause->CompareId());
993 patch_site.EmitPatchInfo(); 993 patch_site.EmitPatchInfo();
994 __ test(eax, eax); 994 __ test(eax, eax);
995 __ j(not_equal, &next_test); 995 __ j(not_equal, &next_test);
996 __ Drop(1); // Switch value is no longer needed. 996 __ Drop(1); // Switch value is no longer needed.
997 __ jmp(clause->body_target()); 997 __ jmp(clause->body_target());
998 } 998 }
999 999
1000 // Discard the test value and jump to the default if present, otherwise to 1000 // Discard the test value and jump to the default if present, otherwise to
1001 // the end of the statement. 1001 // the end of the statement.
1002 __ bind(&next_test); 1002 __ bind(&next_test);
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
1328 // Load next context in chain. 1328 // Load next context in chain.
1329 __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); 1329 __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX));
1330 __ jmp(&next); 1330 __ jmp(&next);
1331 __ bind(&fast); 1331 __ bind(&fast);
1332 } 1332 }
1333 1333
1334 // All extension objects were empty and it is safe to use a global 1334 // All extension objects were empty and it is safe to use a global
1335 // load IC call. 1335 // load IC call.
1336 __ mov(edx, GlobalObjectOperand()); 1336 __ mov(edx, GlobalObjectOperand());
1337 __ mov(ecx, var->name()); 1337 __ mov(ecx, var->name());
1338 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1338 ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
1339 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) 1339 ? NOT_CONTEXTUAL
1340 ? RelocInfo::CODE_TARGET 1340 : CONTEXTUAL;
1341 : RelocInfo::CODE_TARGET_CONTEXT; 1341
1342 Handle<Code> ic = mode == CONTEXTUAL
1343 ? isolate()->builtins()->LoadIC_Initialize_Contextual()
1344 : isolate()->builtins()->LoadIC_Initialize();
1342 CallIC(ic, mode); 1345 CallIC(ic, mode);
1343 } 1346 }
1344 1347
1345 1348
1346 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, 1349 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
1347 Label* slow) { 1350 Label* slow) {
1348 ASSERT(var->IsContextSlot()); 1351 ASSERT(var->IsContextSlot());
1349 Register context = esi; 1352 Register context = esi;
1350 Register temp = ebx; 1353 Register temp = ebx;
1351 1354
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1412 1415
1413 // Three cases: global variables, lookup variables, and all other types of 1416 // Three cases: global variables, lookup variables, and all other types of
1414 // variables. 1417 // variables.
1415 switch (var->location()) { 1418 switch (var->location()) {
1416 case Variable::UNALLOCATED: { 1419 case Variable::UNALLOCATED: {
1417 Comment cmnt(masm_, "Global variable"); 1420 Comment cmnt(masm_, "Global variable");
1418 // Use inline caching. Variable name is passed in ecx and the global 1421 // Use inline caching. Variable name is passed in ecx and the global
1419 // object in eax. 1422 // object in eax.
1420 __ mov(edx, GlobalObjectOperand()); 1423 __ mov(edx, GlobalObjectOperand());
1421 __ mov(ecx, var->name()); 1424 __ mov(ecx, var->name());
1422 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1425 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize_Contextual();
1423 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); 1426 CallIC(ic, CONTEXTUAL);
1424 context()->Plug(eax); 1427 context()->Plug(eax);
1425 break; 1428 break;
1426 } 1429 }
1427 1430
1428 case Variable::PARAMETER: 1431 case Variable::PARAMETER:
1429 case Variable::LOCAL: 1432 case Variable::LOCAL:
1430 case Variable::CONTEXT: { 1433 case Variable::CONTEXT: {
1431 Comment cmnt(masm_, var->IsContextSlot() 1434 Comment cmnt(masm_, var->IsContextSlot()
1432 ? "Context variable" 1435 ? "Context variable"
1433 : "Stack variable"); 1436 : "Stack variable");
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
1632 // Fall through. 1635 // Fall through.
1633 case ObjectLiteral::Property::COMPUTED: 1636 case ObjectLiteral::Property::COMPUTED:
1634 if (key->value()->IsInternalizedString()) { 1637 if (key->value()->IsInternalizedString()) {
1635 if (property->emit_store()) { 1638 if (property->emit_store()) {
1636 VisitForAccumulatorValue(value); 1639 VisitForAccumulatorValue(value);
1637 __ mov(ecx, Immediate(key->value())); 1640 __ mov(ecx, Immediate(key->value()));
1638 __ mov(edx, Operand(esp, 0)); 1641 __ mov(edx, Operand(esp, 0));
1639 Handle<Code> ic = is_classic_mode() 1642 Handle<Code> ic = is_classic_mode()
1640 ? isolate()->builtins()->StoreIC_Initialize() 1643 ? isolate()->builtins()->StoreIC_Initialize()
1641 : isolate()->builtins()->StoreIC_Initialize_Strict(); 1644 : isolate()->builtins()->StoreIC_Initialize_Strict();
1642 CallIC(ic, RelocInfo::CODE_TARGET, key->LiteralFeedbackId()); 1645 CallIC(ic, NOT_CONTEXTUAL, key->LiteralFeedbackId());
1643 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1646 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1644 } else { 1647 } else {
1645 VisitForEffect(value); 1648 VisitForEffect(value);
1646 } 1649 }
1647 break; 1650 break;
1648 } 1651 }
1649 __ push(Operand(esp, 0)); // Duplicate receiver. 1652 __ push(Operand(esp, 0)); // Duplicate receiver.
1650 VisitForStackValue(key); 1653 VisitForStackValue(key);
1651 VisitForStackValue(value); 1654 VisitForStackValue(value);
1652 if (property->emit_store()) { 1655 if (property->emit_store()) {
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after
2211 ecx, edx, kDontSaveFPRegs); 2214 ecx, edx, kDontSaveFPRegs);
2212 } 2215 }
2213 2216
2214 2217
2215 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 2218 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
2216 SetSourcePosition(prop->position()); 2219 SetSourcePosition(prop->position());
2217 Literal* key = prop->key()->AsLiteral(); 2220 Literal* key = prop->key()->AsLiteral();
2218 ASSERT(!key->value()->IsSmi()); 2221 ASSERT(!key->value()->IsSmi());
2219 __ mov(ecx, Immediate(key->value())); 2222 __ mov(ecx, Immediate(key->value()));
2220 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 2223 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
2221 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); 2224 CallIC(ic, NOT_CONTEXTUAL, prop->PropertyFeedbackId());
2222 } 2225 }
2223 2226
2224 2227
2225 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 2228 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
2226 SetSourcePosition(prop->position()); 2229 SetSourcePosition(prop->position());
2227 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2230 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2228 CallIC(ic, RelocInfo::CODE_TARGET, prop->PropertyFeedbackId()); 2231 CallIC(ic, NOT_CONTEXTUAL, prop->PropertyFeedbackId());
2229 } 2232 }
2230 2233
2231 2234
2232 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 2235 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
2233 Token::Value op, 2236 Token::Value op,
2234 OverwriteMode mode, 2237 OverwriteMode mode,
2235 Expression* left, 2238 Expression* left,
2236 Expression* right) { 2239 Expression* right) {
2237 // Do combined smi check of the operands. Left operand is on the 2240 // Do combined smi check of the operands. Left operand is on the
2238 // stack. Right operand is in eax. 2241 // stack. Right operand is in eax.
2239 Label smi_case, done, stub_call; 2242 Label smi_case, done, stub_call;
2240 __ pop(edx); 2243 __ pop(edx);
2241 __ mov(ecx, eax); 2244 __ mov(ecx, eax);
2242 __ or_(eax, edx); 2245 __ or_(eax, edx);
2243 JumpPatchSite patch_site(masm_); 2246 JumpPatchSite patch_site(masm_);
2244 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear); 2247 patch_site.EmitJumpIfSmi(eax, &smi_case, Label::kNear);
2245 2248
2246 __ bind(&stub_call); 2249 __ bind(&stub_call);
2247 __ mov(eax, ecx); 2250 __ mov(eax, ecx);
2248 BinaryOpStub stub(op, mode); 2251 BinaryOpStub stub(op, mode);
2249 CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, 2252 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL,
2250 expr->BinaryOperationFeedbackId()); 2253 expr->BinaryOperationFeedbackId());
2251 patch_site.EmitPatchInfo(); 2254 patch_site.EmitPatchInfo();
2252 __ jmp(&done, Label::kNear); 2255 __ jmp(&done, Label::kNear);
2253 2256
2254 // Smi case. 2257 // Smi case.
2255 __ bind(&smi_case); 2258 __ bind(&smi_case);
2256 __ mov(eax, edx); // Copy left operand in case of a stub call. 2259 __ mov(eax, edx); // Copy left operand in case of a stub call.
2257 2260
2258 switch (op) { 2261 switch (op) {
2259 case Token::SAR: 2262 case Token::SAR:
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
2325 context()->Plug(eax); 2328 context()->Plug(eax);
2326 } 2329 }
2327 2330
2328 2331
2329 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, 2332 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
2330 Token::Value op, 2333 Token::Value op,
2331 OverwriteMode mode) { 2334 OverwriteMode mode) {
2332 __ pop(edx); 2335 __ pop(edx);
2333 BinaryOpStub stub(op, mode); 2336 BinaryOpStub stub(op, mode);
2334 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2337 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
2335 CallIC(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, 2338 CallIC(stub.GetCode(isolate()), NOT_CONTEXTUAL,
2336 expr->BinaryOperationFeedbackId()); 2339 expr->BinaryOperationFeedbackId());
2337 patch_site.EmitPatchInfo(); 2340 patch_site.EmitPatchInfo();
2338 context()->Plug(eax); 2341 context()->Plug(eax);
2339 } 2342 }
2340 2343
2341 2344
2342 void FullCodeGenerator::EmitAssignment(Expression* expr) { 2345 void FullCodeGenerator::EmitAssignment(Expression* expr) {
2343 // Invalid left-hand sides are rewritten by the parser to have a 'throw 2346 // Invalid left-hand sides are rewritten by the parser to have a 'throw
2344 // ReferenceError' on the left-hand side. 2347 // ReferenceError' on the left-hand side.
2345 if (!expr->IsValidLeftHandSide()) { 2348 if (!expr->IsValidLeftHandSide()) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2396 2399
2397 2400
2398 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 2401 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
2399 Token::Value op) { 2402 Token::Value op) {
2400 if (var->IsUnallocated()) { 2403 if (var->IsUnallocated()) {
2401 // Global var, const, or let. 2404 // Global var, const, or let.
2402 __ mov(ecx, var->name()); 2405 __ mov(ecx, var->name());
2403 __ mov(edx, GlobalObjectOperand()); 2406 __ mov(edx, GlobalObjectOperand());
2404 Handle<Code> ic = is_classic_mode() 2407 Handle<Code> ic = is_classic_mode()
2405 ? isolate()->builtins()->StoreIC_Initialize() 2408 ? isolate()->builtins()->StoreIC_Initialize()
2406 : isolate()->builtins()->StoreIC_Initialize_Strict(); 2409 : isolate()->builtins()->StoreIC_Initialize_Contextual_Strict();
2407 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); 2410 CallIC(ic, CONTEXTUAL);
2408
2409 } else if (op == Token::INIT_CONST) { 2411 } else if (op == Token::INIT_CONST) {
2410 // Const initializers need a write barrier. 2412 // Const initializers need a write barrier.
2411 ASSERT(!var->IsParameter()); // No const parameters. 2413 ASSERT(!var->IsParameter()); // No const parameters.
2412 if (var->IsStackLocal()) { 2414 if (var->IsStackLocal()) {
2413 Label skip; 2415 Label skip;
2414 __ mov(edx, StackOperand(var)); 2416 __ mov(edx, StackOperand(var));
2415 __ cmp(edx, isolate()->factory()->the_hole_value()); 2417 __ cmp(edx, isolate()->factory()->the_hole_value());
2416 __ j(not_equal, &skip); 2418 __ j(not_equal, &skip);
2417 __ mov(StackOperand(var), eax); 2419 __ mov(StackOperand(var), eax);
2418 __ bind(&skip); 2420 __ bind(&skip);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
2495 ASSERT(prop != NULL); 2497 ASSERT(prop != NULL);
2496 ASSERT(prop->key()->AsLiteral() != NULL); 2498 ASSERT(prop->key()->AsLiteral() != NULL);
2497 2499
2498 // Record source code position before IC call. 2500 // Record source code position before IC call.
2499 SetSourcePosition(expr->position()); 2501 SetSourcePosition(expr->position());
2500 __ mov(ecx, prop->key()->AsLiteral()->value()); 2502 __ mov(ecx, prop->key()->AsLiteral()->value());
2501 __ pop(edx); 2503 __ pop(edx);
2502 Handle<Code> ic = is_classic_mode() 2504 Handle<Code> ic = is_classic_mode()
2503 ? isolate()->builtins()->StoreIC_Initialize() 2505 ? isolate()->builtins()->StoreIC_Initialize()
2504 : isolate()->builtins()->StoreIC_Initialize_Strict(); 2506 : isolate()->builtins()->StoreIC_Initialize_Strict();
2505 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); 2507 CallIC(ic, NOT_CONTEXTUAL, expr->AssignmentFeedbackId());
2506 2508
2507 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2509 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2508 context()->Plug(eax); 2510 context()->Plug(eax);
2509 } 2511 }
2510 2512
2511 2513
2512 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2514 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2513 // Assignment to a property, using a keyed store IC. 2515 // Assignment to a property, using a keyed store IC.
2514 // eax : value 2516 // eax : value
2515 // esp[0] : key 2517 // esp[0] : key
2516 // esp[kPointerSize] : receiver 2518 // esp[kPointerSize] : receiver
2517 2519
2518 __ pop(ecx); // Key. 2520 __ pop(ecx); // Key.
2519 __ pop(edx); 2521 __ pop(edx);
2520 // Record source code position before IC call. 2522 // Record source code position before IC call.
2521 SetSourcePosition(expr->position()); 2523 SetSourcePosition(expr->position());
2522 Handle<Code> ic = is_classic_mode() 2524 Handle<Code> ic = is_classic_mode()
2523 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2525 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2524 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2526 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2525 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); 2527 CallIC(ic, NOT_CONTEXTUAL, expr->AssignmentFeedbackId());
2526 2528
2527 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2529 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2528 context()->Plug(eax); 2530 context()->Plug(eax);
2529 } 2531 }
2530 2532
2531 2533
2532 void FullCodeGenerator::VisitProperty(Property* expr) { 2534 void FullCodeGenerator::VisitProperty(Property* expr) {
2533 Comment cmnt(masm_, "[ Property"); 2535 Comment cmnt(masm_, "[ Property");
2534 Expression* key = expr->key(); 2536 Expression* key = expr->key();
2535 2537
2536 if (key->IsPropertyName()) { 2538 if (key->IsPropertyName()) {
2537 VisitForAccumulatorValue(expr->obj()); 2539 VisitForAccumulatorValue(expr->obj());
2538 __ mov(edx, result_register()); 2540 __ mov(edx, result_register());
2539 EmitNamedPropertyLoad(expr); 2541 EmitNamedPropertyLoad(expr);
2540 PrepareForBailoutForId(expr->LoadId(), TOS_REG); 2542 PrepareForBailoutForId(expr->LoadId(), TOS_REG);
2541 context()->Plug(eax); 2543 context()->Plug(eax);
2542 } else { 2544 } else {
2543 VisitForStackValue(expr->obj()); 2545 VisitForStackValue(expr->obj());
2544 VisitForAccumulatorValue(expr->key()); 2546 VisitForAccumulatorValue(expr->key());
2545 __ pop(edx); // Object. 2547 __ pop(edx); // Object.
2546 __ mov(ecx, result_register()); // Key. 2548 __ mov(ecx, result_register()); // Key.
2547 EmitKeyedPropertyLoad(expr); 2549 EmitKeyedPropertyLoad(expr);
2548 context()->Plug(eax); 2550 context()->Plug(eax);
2549 } 2551 }
2550 } 2552 }
2551 2553
2552 2554
2553 void FullCodeGenerator::CallIC(Handle<Code> code, 2555 void FullCodeGenerator::CallIC(Handle<Code> code,
2554 RelocInfo::Mode rmode, 2556 ContextualMode mode,
2555 TypeFeedbackId ast_id) { 2557 TypeFeedbackId ast_id) {
2556 ic_total_count_++; 2558 ic_total_count_++;
2557 __ call(code, rmode, ast_id); 2559 ASSERT(mode != CONTEXTUAL || ast_id.IsNone());
2560 __ call(code, RelocInfo::CODE_TARGET, ast_id);
2558 } 2561 }
2559 2562
2560 2563
2561 2564
2562 2565
2563 void FullCodeGenerator::EmitCallWithIC(Call* expr, 2566 void FullCodeGenerator::EmitCallWithIC(Call* expr,
2564 Handle<Object> name, 2567 Handle<Object> name,
2565 RelocInfo::Mode mode) { 2568 ContextualMode mode) {
2566 // Code common for calls using the IC. 2569 // Code common for calls using the IC.
2567 ZoneList<Expression*>* args = expr->arguments(); 2570 ZoneList<Expression*>* args = expr->arguments();
2568 int arg_count = args->length(); 2571 int arg_count = args->length();
2569 { PreservePositionScope scope(masm()->positions_recorder()); 2572 { PreservePositionScope scope(masm()->positions_recorder());
2570 for (int i = 0; i < arg_count; i++) { 2573 for (int i = 0; i < arg_count; i++) {
2571 VisitForStackValue(args->at(i)); 2574 VisitForStackValue(args->at(i));
2572 } 2575 }
2573 __ Set(ecx, Immediate(name)); 2576 __ Set(ecx, Immediate(name));
2574 } 2577 }
2575 // Record source position of the IC call. 2578 // Record source position of the IC call.
2576 SetSourcePosition(expr->position()); 2579 SetSourcePosition(expr->position());
2577 Handle<Code> ic = 2580 Handle<Code> ic =
2578 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); 2581 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
2579 CallIC(ic, mode, expr->CallFeedbackId()); 2582 TypeFeedbackId ast_id = mode == CONTEXTUAL
2583 ? TypeFeedbackId::None()
2584 : expr->CallFeedbackId();
2585 CallIC(ic, mode, ast_id);
2580 RecordJSReturnSite(expr); 2586 RecordJSReturnSite(expr);
2581 // Restore context register. 2587 // Restore context register.
2582 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2588 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2583 context()->Plug(eax); 2589 context()->Plug(eax);
2584 } 2590 }
2585 2591
2586 2592
2587 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2593 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
2588 Expression* key) { 2594 Expression* key) {
2589 // Load the key. 2595 // Load the key.
(...skipping 11 matching lines...) Expand all
2601 { PreservePositionScope scope(masm()->positions_recorder()); 2607 { PreservePositionScope scope(masm()->positions_recorder());
2602 for (int i = 0; i < arg_count; i++) { 2608 for (int i = 0; i < arg_count; i++) {
2603 VisitForStackValue(args->at(i)); 2609 VisitForStackValue(args->at(i));
2604 } 2610 }
2605 } 2611 }
2606 // Record source position of the IC call. 2612 // Record source position of the IC call.
2607 SetSourcePosition(expr->position()); 2613 SetSourcePosition(expr->position());
2608 Handle<Code> ic = 2614 Handle<Code> ic =
2609 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count); 2615 isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count);
2610 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key. 2616 __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key.
2611 CallIC(ic, RelocInfo::CODE_TARGET, expr->CallFeedbackId()); 2617 CallIC(ic, NOT_CONTEXTUAL, expr->CallFeedbackId());
2612 RecordJSReturnSite(expr); 2618 RecordJSReturnSite(expr);
2613 // Restore context register. 2619 // Restore context register.
2614 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2620 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2615 context()->DropAndPlug(1, eax); // Drop the key still on the stack. 2621 context()->DropAndPlug(1, eax); // Drop the key still on the stack.
2616 } 2622 }
2617 2623
2618 2624
2619 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { 2625 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) {
2620 // Code common for calls using the call stub. 2626 // Code common for calls using the call stub.
2621 ZoneList<Expression*>* args = expr->arguments(); 2627 ZoneList<Expression*>* args = expr->arguments();
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
2711 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); 2717 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
2712 __ CallStub(&stub); 2718 __ CallStub(&stub);
2713 RecordJSReturnSite(expr); 2719 RecordJSReturnSite(expr);
2714 // Restore context register. 2720 // Restore context register.
2715 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 2721 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
2716 context()->DropAndPlug(1, eax); 2722 context()->DropAndPlug(1, eax);
2717 2723
2718 } else if (proxy != NULL && proxy->var()->IsUnallocated()) { 2724 } else if (proxy != NULL && proxy->var()->IsUnallocated()) {
2719 // Push global object as receiver for the call IC. 2725 // Push global object as receiver for the call IC.
2720 __ push(GlobalObjectOperand()); 2726 __ push(GlobalObjectOperand());
2721 EmitCallWithIC(expr, proxy->name(), RelocInfo::CODE_TARGET_CONTEXT); 2727 EmitCallWithIC(expr, proxy->name(), CONTEXTUAL);
2722
2723 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { 2728 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
2724 // Call to a lookup slot (dynamically introduced variable). 2729 // Call to a lookup slot (dynamically introduced variable).
2725 Label slow, done; 2730 Label slow, done;
2726 { PreservePositionScope scope(masm()->positions_recorder()); 2731 { PreservePositionScope scope(masm()->positions_recorder());
2727 // Generate code for loading from variables potentially shadowed by 2732 // Generate code for loading from variables potentially shadowed by
2728 // eval-introduced variables. 2733 // eval-introduced variables.
2729 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); 2734 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done);
2730 } 2735 }
2731 __ bind(&slow); 2736 __ bind(&slow);
2732 // Call the runtime to find the function to call (returned in eax) and 2737 // Call the runtime to find the function to call (returned in eax) and
(...skipping 23 matching lines...) Expand all
2756 // implicitly the global object. 2761 // implicitly the global object.
2757 EmitCallWithStub(expr, RECEIVER_MIGHT_BE_IMPLICIT); 2762 EmitCallWithStub(expr, RECEIVER_MIGHT_BE_IMPLICIT);
2758 2763
2759 } else if (property != NULL) { 2764 } else if (property != NULL) {
2760 { PreservePositionScope scope(masm()->positions_recorder()); 2765 { PreservePositionScope scope(masm()->positions_recorder());
2761 VisitForStackValue(property->obj()); 2766 VisitForStackValue(property->obj());
2762 } 2767 }
2763 if (property->key()->IsPropertyName()) { 2768 if (property->key()->IsPropertyName()) {
2764 EmitCallWithIC(expr, 2769 EmitCallWithIC(expr,
2765 property->key()->AsLiteral()->value(), 2770 property->key()->AsLiteral()->value(),
2766 RelocInfo::CODE_TARGET); 2771 NOT_CONTEXTUAL);
2767 } else { 2772 } else {
2768 EmitKeyedCallWithIC(expr, property->key()); 2773 EmitKeyedCallWithIC(expr, property->key());
2769 } 2774 }
2770 2775
2771 } else { 2776 } else {
2772 // Call to an arbitrary expression not handled specially above. 2777 // Call to an arbitrary expression not handled specially above.
2773 { PreservePositionScope scope(masm()->positions_recorder()); 2778 { PreservePositionScope scope(masm()->positions_recorder());
2774 VisitForStackValue(callee); 2779 VisitForStackValue(callee);
2775 } 2780 }
2776 // Load global receiver object. 2781 // Load global receiver object.
(...skipping 1372 matching lines...) Expand 10 before | Expand all | Expand 10 after
4149 4154
4150 // Push the arguments ("left-to-right"). 4155 // Push the arguments ("left-to-right").
4151 int arg_count = args->length(); 4156 int arg_count = args->length();
4152 for (int i = 0; i < arg_count; i++) { 4157 for (int i = 0; i < arg_count; i++) {
4153 VisitForStackValue(args->at(i)); 4158 VisitForStackValue(args->at(i));
4154 } 4159 }
4155 4160
4156 if (expr->is_jsruntime()) { 4161 if (expr->is_jsruntime()) {
4157 // Call the JS runtime function via a call IC. 4162 // Call the JS runtime function via a call IC.
4158 __ Set(ecx, Immediate(expr->name())); 4163 __ Set(ecx, Immediate(expr->name()));
4159 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; 4164 ContextualMode mode = NOT_CONTEXTUAL;
4160 Handle<Code> ic = 4165 Handle<Code> ic =
4161 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode); 4166 isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
4162 CallIC(ic, mode, expr->CallRuntimeFeedbackId()); 4167 CallIC(ic, mode, expr->CallRuntimeFeedbackId());
4163 // Restore context register. 4168 // Restore context register.
4164 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 4169 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
4165 } else { 4170 } else {
4166 // Call the C runtime function. 4171 // Call the C runtime function.
4167 __ CallRuntime(expr->function(), arg_count); 4172 __ CallRuntime(expr->function(), arg_count);
4168 } 4173 }
4169 context()->Plug(eax); 4174 context()->Plug(eax);
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
4409 4414
4410 // Record position before stub call. 4415 // Record position before stub call.
4411 SetSourcePosition(expr->position()); 4416 SetSourcePosition(expr->position());
4412 4417
4413 // Call stub for +1/-1. 4418 // Call stub for +1/-1.
4414 __ bind(&stub_call); 4419 __ bind(&stub_call);
4415 __ mov(edx, eax); 4420 __ mov(edx, eax);
4416 __ mov(eax, Immediate(Smi::FromInt(1))); 4421 __ mov(eax, Immediate(Smi::FromInt(1)));
4417 BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE); 4422 BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE);
4418 CallIC(stub.GetCode(isolate()), 4423 CallIC(stub.GetCode(isolate()),
4419 RelocInfo::CODE_TARGET, 4424 NOT_CONTEXTUAL,
4420 expr->CountBinOpFeedbackId()); 4425 expr->CountBinOpFeedbackId());
4421 patch_site.EmitPatchInfo(); 4426 patch_site.EmitPatchInfo();
4422 __ bind(&done); 4427 __ bind(&done);
4423 4428
4424 // Store the value returned in eax. 4429 // Store the value returned in eax.
4425 switch (assign_type) { 4430 switch (assign_type) {
4426 case VARIABLE: 4431 case VARIABLE:
4427 if (expr->is_postfix()) { 4432 if (expr->is_postfix()) {
4428 // Perform the assignment as if via '='. 4433 // Perform the assignment as if via '='.
4429 { EffectContext context(this); 4434 { EffectContext context(this);
(...skipping 14 matching lines...) Expand all
4444 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4449 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4445 context()->Plug(eax); 4450 context()->Plug(eax);
4446 } 4451 }
4447 break; 4452 break;
4448 case NAMED_PROPERTY: { 4453 case NAMED_PROPERTY: {
4449 __ mov(ecx, prop->key()->AsLiteral()->value()); 4454 __ mov(ecx, prop->key()->AsLiteral()->value());
4450 __ pop(edx); 4455 __ pop(edx);
4451 Handle<Code> ic = is_classic_mode() 4456 Handle<Code> ic = is_classic_mode()
4452 ? isolate()->builtins()->StoreIC_Initialize() 4457 ? isolate()->builtins()->StoreIC_Initialize()
4453 : isolate()->builtins()->StoreIC_Initialize_Strict(); 4458 : isolate()->builtins()->StoreIC_Initialize_Strict();
4454 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); 4459 CallIC(ic, NOT_CONTEXTUAL, expr->CountStoreFeedbackId());
4455 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4460 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4456 if (expr->is_postfix()) { 4461 if (expr->is_postfix()) {
4457 if (!context()->IsEffect()) { 4462 if (!context()->IsEffect()) {
4458 context()->PlugTOS(); 4463 context()->PlugTOS();
4459 } 4464 }
4460 } else { 4465 } else {
4461 context()->Plug(eax); 4466 context()->Plug(eax);
4462 } 4467 }
4463 break; 4468 break;
4464 } 4469 }
4465 case KEYED_PROPERTY: { 4470 case KEYED_PROPERTY: {
4466 __ pop(ecx); 4471 __ pop(ecx);
4467 __ pop(edx); 4472 __ pop(edx);
4468 Handle<Code> ic = is_classic_mode() 4473 Handle<Code> ic = is_classic_mode()
4469 ? isolate()->builtins()->KeyedStoreIC_Initialize() 4474 ? isolate()->builtins()->KeyedStoreIC_Initialize()
4470 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 4475 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
4471 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); 4476 CallIC(ic, NOT_CONTEXTUAL, expr->CountStoreFeedbackId());
4472 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4477 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4473 if (expr->is_postfix()) { 4478 if (expr->is_postfix()) {
4474 // Result is on the stack 4479 // Result is on the stack
4475 if (!context()->IsEffect()) { 4480 if (!context()->IsEffect()) {
4476 context()->PlugTOS(); 4481 context()->PlugTOS();
4477 } 4482 }
4478 } else { 4483 } else {
4479 context()->Plug(eax); 4484 context()->Plug(eax);
4480 } 4485 }
4481 break; 4486 break;
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
4651 __ or_(ecx, eax); 4656 __ or_(ecx, eax);
4652 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); 4657 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear);
4653 __ cmp(edx, eax); 4658 __ cmp(edx, eax);
4654 Split(cc, if_true, if_false, NULL); 4659 Split(cc, if_true, if_false, NULL);
4655 __ bind(&slow_case); 4660 __ bind(&slow_case);
4656 } 4661 }
4657 4662
4658 // Record position and call the compare IC. 4663 // Record position and call the compare IC.
4659 SetSourcePosition(expr->position()); 4664 SetSourcePosition(expr->position());
4660 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); 4665 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
4661 CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); 4666 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId());
4662 patch_site.EmitPatchInfo(); 4667 patch_site.EmitPatchInfo();
4663 4668
4664 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 4669 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
4665 __ test(eax, eax); 4670 __ test(eax, eax);
4666 Split(cc, if_true, if_false, fall_through); 4671 Split(cc, if_true, if_false, fall_through);
4667 } 4672 }
4668 } 4673 }
4669 4674
4670 // Convert the result of the comparison into one expected for this 4675 // Convert the result of the comparison into one expected for this
4671 // expression's context. 4676 // expression's context.
(...skipping 15 matching lines...) Expand all
4687 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); 4692 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
4688 4693
4689 Handle<Object> nil_value = nil == kNullValue 4694 Handle<Object> nil_value = nil == kNullValue
4690 ? isolate()->factory()->null_value() 4695 ? isolate()->factory()->null_value()
4691 : isolate()->factory()->undefined_value(); 4696 : isolate()->factory()->undefined_value();
4692 if (expr->op() == Token::EQ_STRICT) { 4697 if (expr->op() == Token::EQ_STRICT) {
4693 __ cmp(eax, nil_value); 4698 __ cmp(eax, nil_value);
4694 Split(equal, if_true, if_false, fall_through); 4699 Split(equal, if_true, if_false, fall_through);
4695 } else { 4700 } else {
4696 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil); 4701 Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil);
4697 CallIC(ic, RelocInfo::CODE_TARGET, expr->CompareOperationFeedbackId()); 4702 CallIC(ic, NOT_CONTEXTUAL, expr->CompareOperationFeedbackId());
4698 __ test(eax, eax); 4703 __ test(eax, eax);
4699 Split(not_zero, if_true, if_false, fall_through); 4704 Split(not_zero, if_true, if_false, fall_through);
4700 } 4705 }
4701 context()->Plug(if_true, if_false); 4706 context()->Plug(if_true, if_false);
4702 } 4707 }
4703 4708
4704 4709
4705 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) { 4710 void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
4706 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 4711 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
4707 context()->Plug(eax); 4712 context()->Plug(eax);
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
4913 4918
4914 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), 4919 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(),
4915 Assembler::target_address_at(call_target_address)); 4920 Assembler::target_address_at(call_target_address));
4916 return OSR_AFTER_STACK_CHECK; 4921 return OSR_AFTER_STACK_CHECK;
4917 } 4922 }
4918 4923
4919 4924
4920 } } // namespace v8::internal 4925 } } // namespace v8::internal
4921 4926
4922 #endif // V8_TARGET_ARCH_IA32 4927 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« src/builtins.cc ('K') | « src/full-codegen.h ('k') | src/ia32/ic-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698