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

Side by Side Diff: src/hydrogen.cc

Issue 10837165: Lattice-based representation inference, powered by left/right specific type feedback for BinaryOps … (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: review feedback; fixed tests Created 8 years, 1 month 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
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 HDeoptimize* instr = new(zone()) HDeoptimize(environment->length(), zone()); 126 HDeoptimize* instr = new(zone()) HDeoptimize(environment->length(), zone());
127 for (int i = 0; i < environment->length(); i++) { 127 for (int i = 0; i < environment->length(); i++) {
128 HValue* val = environment->values()->at(i); 128 HValue* val = environment->values()->at(i);
129 instr->AddEnvironmentValue(val, zone()); 129 instr->AddEnvironmentValue(val, zone());
130 } 130 }
131 131
132 return instr; 132 return instr;
133 } 133 }
134 134
135 135
136 HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id) { 136 HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id,
137 RemovableSimulate removable) {
137 ASSERT(HasEnvironment()); 138 ASSERT(HasEnvironment());
138 HEnvironment* environment = last_environment(); 139 HEnvironment* environment = last_environment();
139 ASSERT(ast_id.IsNone() || 140 ASSERT(ast_id.IsNone() ||
140 environment->closure()->shared()->VerifyBailoutId(ast_id)); 141 environment->closure()->shared()->VerifyBailoutId(ast_id));
141 142
142 int push_count = environment->push_count(); 143 int push_count = environment->push_count();
143 int pop_count = environment->pop_count(); 144 int pop_count = environment->pop_count();
144 145
145 HSimulate* instr = new(zone()) HSimulate(ast_id, pop_count, zone()); 146 HSimulate* instr =
146 for (int i = push_count - 1; i >= 0; --i) { 147 new(zone()) HSimulate(ast_id, pop_count, zone(), removable);
148 // Order of pushed values: newest (top of stack) first. This allows
149 // HSimulate::MergeInto() to easily append additional pushed values
150 // that are older (from further down the stack).
151 for (int i = 0; i < push_count; ++i) {
147 instr->AddPushedValue(environment->ExpressionStackAt(i)); 152 instr->AddPushedValue(environment->ExpressionStackAt(i));
148 } 153 }
149 for (int i = 0; i < environment->assigned_variables()->length(); ++i) { 154 for (int i = 0; i < environment->assigned_variables()->length(); ++i) {
150 int index = environment->assigned_variables()->at(i); 155 int index = environment->assigned_variables()->at(i);
151 instr->AddAssignedValue(index, environment->Lookup(index)); 156 instr->AddAssignedValue(index, environment->Lookup(index));
152 } 157 }
153 environment->ClearHistory(); 158 environment->ClearHistory();
154 return instr; 159 return instr;
155 } 160 }
156 161
(...skipping 1127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1284 Analyze(block->dominated_blocks()->at(i)); 1289 Analyze(block->dominated_blocks()->at(i));
1285 } 1290 }
1286 1291
1287 RollBackTo(last_changed_range); 1292 RollBackTo(last_changed_range);
1288 } 1293 }
1289 1294
1290 1295
1291 void HRangeAnalysis::InferControlFlowRange(HCompareIDAndBranch* test, 1296 void HRangeAnalysis::InferControlFlowRange(HCompareIDAndBranch* test,
1292 HBasicBlock* dest) { 1297 HBasicBlock* dest) {
1293 ASSERT((test->FirstSuccessor() == dest) == (test->SecondSuccessor() != dest)); 1298 ASSERT((test->FirstSuccessor() == dest) == (test->SecondSuccessor() != dest));
1294 if (test->GetInputRepresentation().IsInteger32()) { 1299 if (test->representation().IsInteger32()) {
1295 Token::Value op = test->token(); 1300 Token::Value op = test->token();
1296 if (test->SecondSuccessor() == dest) { 1301 if (test->SecondSuccessor() == dest) {
1297 op = Token::NegateCompareOp(op); 1302 op = Token::NegateCompareOp(op);
1298 } 1303 }
1299 Token::Value inverted_op = Token::InvertCompareOp(op); 1304 Token::Value inverted_op = Token::InvertCompareOp(op);
1300 UpdateControlFlowRange(op, test->left(), test->right()); 1305 UpdateControlFlowRange(op, test->left(), test->right());
1301 UpdateControlFlowRange(inverted_op, test->right(), test->left()); 1306 UpdateControlFlowRange(inverted_op, test->right(), test->left());
1302 } 1307 }
1303 } 1308 }
1304 1309
(...skipping 927 matching lines...) Expand 10 before | Expand all | Expand 10 after
2232 dominated); 2237 dominated);
2233 successor_map->Kill(side_effects_on_all_paths); 2238 successor_map->Kill(side_effects_on_all_paths);
2234 successor_dominators->Kill(side_effects_on_all_paths); 2239 successor_dominators->Kill(side_effects_on_all_paths);
2235 } 2240 }
2236 } 2241 }
2237 current = next; 2242 current = next;
2238 } 2243 }
2239 } 2244 }
2240 2245
2241 2246
2242 class HInferRepresentation BASE_EMBEDDED {
2243 public:
2244 explicit HInferRepresentation(HGraph* graph)
2245 : graph_(graph),
2246 worklist_(8, graph->zone()),
2247 in_worklist_(graph->GetMaximumValueID(), graph->zone()) { }
2248
2249 void Analyze();
2250
2251 private:
2252 Representation TryChange(HValue* current);
2253 void AddToWorklist(HValue* current);
2254 void InferBasedOnInputs(HValue* current);
2255 void AddDependantsToWorklist(HValue* current);
2256 void InferBasedOnUses(HValue* current);
2257
2258 Zone* zone() const { return graph_->zone(); }
2259
2260 HGraph* graph_;
2261 ZoneList<HValue*> worklist_;
2262 BitVector in_worklist_;
2263 };
2264
2265
2266 void HInferRepresentation::AddToWorklist(HValue* current) { 2247 void HInferRepresentation::AddToWorklist(HValue* current) {
2267 if (current->representation().IsSpecialization()) return; 2248 if (current->representation().IsTagged()) return;
2268 if (!current->CheckFlag(HValue::kFlexibleRepresentation)) return; 2249 if (!current->CheckFlag(HValue::kFlexibleRepresentation)) return;
2269 if (in_worklist_.Contains(current->id())) return; 2250 if (in_worklist_.Contains(current->id())) return;
2270 worklist_.Add(current, zone()); 2251 worklist_.Add(current, zone());
2271 in_worklist_.Add(current->id()); 2252 in_worklist_.Add(current->id());
2272 } 2253 }
2273 2254
2274 2255
2275 // This method tries to specialize the representation type of the value
2276 // given as a parameter. The value is asked to infer its representation type
2277 // based on its inputs. If the inferred type is more specialized, then this
2278 // becomes the new representation type of the node.
2279 void HInferRepresentation::InferBasedOnInputs(HValue* current) {
2280 Representation r = current->representation();
2281 if (r.IsSpecialization()) return;
2282 ASSERT(current->CheckFlag(HValue::kFlexibleRepresentation));
2283 Representation inferred = current->InferredRepresentation();
2284 if (inferred.IsSpecialization()) {
2285 if (FLAG_trace_representation) {
2286 PrintF("Changing #%d representation %s -> %s based on inputs\n",
2287 current->id(),
2288 r.Mnemonic(),
2289 inferred.Mnemonic());
2290 }
2291 current->ChangeRepresentation(inferred);
2292 AddDependantsToWorklist(current);
2293 }
2294 }
2295
2296
2297 void HInferRepresentation::AddDependantsToWorklist(HValue* value) {
2298 for (HUseIterator it(value->uses()); !it.Done(); it.Advance()) {
2299 AddToWorklist(it.value());
2300 }
2301 for (int i = 0; i < value->OperandCount(); ++i) {
2302 AddToWorklist(value->OperandAt(i));
2303 }
2304 }
2305
2306
2307 // This method calculates whether specializing the representation of the value
2308 // given as the parameter has a benefit in terms of less necessary type
2309 // conversions. If there is a benefit, then the representation of the value is
2310 // specialized.
2311 void HInferRepresentation::InferBasedOnUses(HValue* value) {
2312 Representation r = value->representation();
2313 if (r.IsSpecialization() || value->HasNoUses()) return;
2314 ASSERT(value->CheckFlag(HValue::kFlexibleRepresentation));
2315 Representation new_rep = TryChange(value);
2316 if (!new_rep.IsNone()) {
2317 if (!value->representation().Equals(new_rep)) {
2318 if (FLAG_trace_representation) {
2319 PrintF("Changing #%d representation %s -> %s based on uses\n",
2320 value->id(),
2321 r.Mnemonic(),
2322 new_rep.Mnemonic());
2323 }
2324 value->ChangeRepresentation(new_rep);
2325 AddDependantsToWorklist(value);
2326 }
2327 }
2328 }
2329
2330
2331 Representation HInferRepresentation::TryChange(HValue* value) {
2332 // Array of use counts for each representation.
2333 int use_count[Representation::kNumRepresentations] = { 0 };
2334
2335 for (HUseIterator it(value->uses()); !it.Done(); it.Advance()) {
2336 HValue* use = it.value();
2337 Representation rep = use->ObservedInputRepresentation(it.index());
2338 if (rep.IsNone()) continue;
2339 if (FLAG_trace_representation) {
2340 PrintF("%d %s is used by %d %s as %s\n",
2341 value->id(),
2342 value->Mnemonic(),
2343 use->id(),
2344 use->Mnemonic(),
2345 rep.Mnemonic());
2346 }
2347 if (use->IsPhi()) HPhi::cast(use)->AddIndirectUsesTo(&use_count[0]);
2348 use_count[rep.kind()] += use->LoopWeight();
2349 }
2350 int tagged_count = use_count[Representation::kTagged];
2351 int double_count = use_count[Representation::kDouble];
2352 int int32_count = use_count[Representation::kInteger32];
2353 int non_tagged_count = double_count + int32_count;
2354
2355 // If a non-loop phi has tagged uses, don't convert it to untagged.
2356 if (value->IsPhi() && !value->block()->IsLoopHeader() && tagged_count > 0) {
2357 return Representation::None();
2358 }
2359
2360 // Prefer unboxing over boxing, the latter is more expensive.
2361 if (tagged_count > non_tagged_count) return Representation::None();
2362
2363 // Prefer Integer32 over Double, if possible.
2364 if (int32_count > 0 && value->IsConvertibleToInteger()) {
2365 return Representation::Integer32();
2366 }
2367
2368 if (double_count > 0) return Representation::Double();
2369
2370 return Representation::None();
2371 }
2372
2373
2374 void HInferRepresentation::Analyze() { 2256 void HInferRepresentation::Analyze() {
2375 HPhase phase("H_Infer representations", graph_); 2257 HPhase phase("H_Infer representations", graph_);
2376 2258
2377 // (1) Initialize bit vectors and count real uses. Each phi gets a 2259 // (1) Initialize bit vectors and count real uses. Each phi gets a
2378 // bit-vector of length <number of phis>. 2260 // bit-vector of length <number of phis>.
2379 const ZoneList<HPhi*>* phi_list = graph_->phi_list(); 2261 const ZoneList<HPhi*>* phi_list = graph_->phi_list();
2380 int phi_count = phi_list->length(); 2262 int phi_count = phi_list->length();
2381 ZoneList<BitVector*> connected_phis(phi_count, graph_->zone()); 2263 ZoneList<BitVector*> connected_phis(phi_count, graph_->zone());
2382 for (int i = 0; i < phi_count; ++i) { 2264 for (int i = 0; i < phi_count; ++i) {
2383 phi_list->at(i)->InitRealUses(i); 2265 phi_list->at(i)->InitRealUses(i);
(...skipping 30 matching lines...) Expand all
2414 for (int i = 0; i < phi_count; ++i) { 2296 for (int i = 0; i < phi_count; ++i) {
2415 HPhi* phi = phi_list->at(i); 2297 HPhi* phi = phi_list->at(i);
2416 bool cti = phi->AllOperandsConvertibleToInteger(); 2298 bool cti = phi->AllOperandsConvertibleToInteger();
2417 if (cti) continue; 2299 if (cti) continue;
2418 2300
2419 for (BitVector::Iterator it(connected_phis.at(i)); 2301 for (BitVector::Iterator it(connected_phis.at(i));
2420 !it.Done(); 2302 !it.Done();
2421 it.Advance()) { 2303 it.Advance()) {
2422 HPhi* phi = phi_list->at(it.Current()); 2304 HPhi* phi = phi_list->at(it.Current());
2423 phi->set_is_convertible_to_integer(false); 2305 phi->set_is_convertible_to_integer(false);
2424 phi->ResetInteger32Uses();
2425 } 2306 }
2426 } 2307 }
2427 2308
2428 // (3b) Use the phi reachability information from step 2 to 2309 // (3b) Use the phi reachability information from step 2 to
2429 // sum up the non-phi use counts of all connected phis. 2310 // sum up the non-phi use counts of all connected phis.
2430 for (int i = 0; i < phi_count; ++i) { 2311 for (int i = 0; i < phi_count; ++i) {
2431 HPhi* phi = phi_list->at(i); 2312 HPhi* phi = phi_list->at(i);
2432 for (BitVector::Iterator it(connected_phis.at(i)); 2313 for (BitVector::Iterator it(connected_phis.at(i));
2433 !it.Done(); 2314 !it.Done();
2434 it.Advance()) { 2315 it.Advance()) {
(...skipping 15 matching lines...) Expand all
2450 while (current != NULL) { 2331 while (current != NULL) {
2451 AddToWorklist(current); 2332 AddToWorklist(current);
2452 current = current->next(); 2333 current = current->next();
2453 } 2334 }
2454 } 2335 }
2455 2336
2456 // Do a fixed point iteration, trying to improve representations 2337 // Do a fixed point iteration, trying to improve representations
2457 while (!worklist_.is_empty()) { 2338 while (!worklist_.is_empty()) {
2458 HValue* current = worklist_.RemoveLast(); 2339 HValue* current = worklist_.RemoveLast();
2459 in_worklist_.Remove(current->id()); 2340 in_worklist_.Remove(current->id());
2460 InferBasedOnInputs(current); 2341 current->InferRepresentation(this);
2461 InferBasedOnUses(current); 2342 }
2343
2344 // Lastly: any instruction that we don't have representation information
2345 // for defaults to Tagged.
2346 for (int i = 0; i < graph_->blocks()->length(); ++i) {
2347 HBasicBlock* block = graph_->blocks()->at(i);
2348 const ZoneList<HPhi*>* phis = block->phis();
2349 for (int j = 0; j < phis->length(); ++j) {
2350 HPhi* phi = phis->at(j);
2351 if (phi->representation().IsNone()) {
2352 phi->ChangeRepresentation(Representation::Tagged());
2353 }
2354 }
2355 for (HInstruction* current = block->first();
2356 current != NULL; current = current->next()) {
2357 if (current->representation().IsNone() &&
2358 current->CheckFlag(HInstruction::kFlexibleRepresentation)) {
2359 current->ChangeRepresentation(Representation::Tagged());
2360 }
2361 }
2462 } 2362 }
2463 } 2363 }
2464 2364
2365
2366 void HGraph::MergeRemovableSimulates() {
2367 for (int i = 0; i < blocks()->length(); ++i) {
2368 HBasicBlock* block = blocks()->at(i);
2369 // Always reset the folding candidate at the start of a block.
2370 HSimulate* folding_candidate = NULL;
2371 // Nasty heuristic: Never remove the first simulate in a block. This
2372 // just so happens to have a beneficial effect on register allocation.
2373 bool first = true;
2374 for (HInstruction* current = block->first();
2375 current != NULL; current = current->next()) {
2376 if (current->IsLeaveInlined()) {
2377 // Never fold simulates from inlined environments into simulates
2378 // in the outer environment.
2379 // (Before each HEnterInlined, there is a non-foldable HSimulate
2380 // anyway, so we get the barrier in the other direction for free.)
2381 if (folding_candidate != NULL) {
2382 folding_candidate->DeleteAndReplaceWith(NULL);
2383 }
2384 folding_candidate = NULL;
2385 continue;
2386 }
2387 // If we have an HSimulate and a candidate, perform the folding.
2388 if (!current->IsSimulate()) continue;
2389 if (first) {
2390 first = false;
2391 continue;
2392 }
2393 HSimulate* current_simulate = HSimulate::cast(current);
2394 if (folding_candidate != NULL) {
2395 folding_candidate->MergeInto(current_simulate);
2396 folding_candidate->DeleteAndReplaceWith(NULL);
2397 folding_candidate = NULL;
2398 }
2399 // Check if the current simulate is a candidate for folding.
2400 if (current_simulate->previous()->HasObservableSideEffects() &&
2401 !current_simulate->next()->IsSimulate()) {
2402 continue;
2403 }
2404 if (!current_simulate->is_candidate_for_removal()) {
2405 continue;
2406 }
2407 folding_candidate = current_simulate;
2408 }
2409 }
2410 }
2411
2465 2412
2466 void HGraph::InitializeInferredTypes() { 2413 void HGraph::InitializeInferredTypes() {
2467 HPhase phase("H_Inferring types", this); 2414 HPhase phase("H_Inferring types", this);
2468 InitializeInferredTypes(0, this->blocks_.length() - 1); 2415 InitializeInferredTypes(0, this->blocks_.length() - 1);
2469 } 2416 }
2470 2417
2471 2418
2472 void HGraph::InitializeInferredTypes(int from_inclusive, int to_inclusive) { 2419 void HGraph::InitializeInferredTypes(int from_inclusive, int to_inclusive) {
2473 for (int i = from_inclusive; i <= to_inclusive; ++i) { 2420 for (int i = from_inclusive; i <= to_inclusive; ++i) {
2474 HBasicBlock* block = blocks_[i]; 2421 HBasicBlock* block = blocks_[i];
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2546 int use_index, 2493 int use_index,
2547 Representation to) { 2494 Representation to) {
2548 // Insert the representation change right before its use. For phi-uses we 2495 // Insert the representation change right before its use. For phi-uses we
2549 // insert at the end of the corresponding predecessor. 2496 // insert at the end of the corresponding predecessor.
2550 HInstruction* next = NULL; 2497 HInstruction* next = NULL;
2551 if (use_value->IsPhi()) { 2498 if (use_value->IsPhi()) {
2552 next = use_value->block()->predecessors()->at(use_index)->end(); 2499 next = use_value->block()->predecessors()->at(use_index)->end();
2553 } else { 2500 } else {
2554 next = HInstruction::cast(use_value); 2501 next = HInstruction::cast(use_value);
2555 } 2502 }
2556
2557 // For constants we try to make the representation change at compile 2503 // For constants we try to make the representation change at compile
2558 // time. When a representation change is not possible without loss of 2504 // time. When a representation change is not possible without loss of
2559 // information we treat constants like normal instructions and insert the 2505 // information we treat constants like normal instructions and insert the
2560 // change instructions for them. 2506 // change instructions for them.
2561 HInstruction* new_value = NULL; 2507 HInstruction* new_value = NULL;
2562 bool is_truncating = use_value->CheckFlag(HValue::kTruncatingToInt32); 2508 bool is_truncating = use_value->CheckFlag(HValue::kTruncatingToInt32);
2563 bool deoptimize_on_undefined = 2509 bool deoptimize_on_undefined =
2564 use_value->CheckFlag(HValue::kDeoptimizeOnUndefined); 2510 use_value->CheckFlag(HValue::kDeoptimizeOnUndefined);
2565 if (value->IsConstant()) { 2511 if (value->IsConstant()) {
2566 HConstant* constant = HConstant::cast(value); 2512 HConstant* constant = HConstant::cast(value);
2567 // Try to create a new copy of the constant with the new representation. 2513 // Try to create a new copy of the constant with the new representation.
2568 new_value = is_truncating 2514 new_value = (is_truncating && to.IsInteger32())
2569 ? constant->CopyToTruncatedInt32(zone()) 2515 ? constant->CopyToTruncatedInt32(zone())
2570 : constant->CopyToRepresentation(to, zone()); 2516 : constant->CopyToRepresentation(to, zone());
2571 } 2517 }
2572 2518
2573 if (new_value == NULL) { 2519 if (new_value == NULL) {
2574 new_value = new(zone()) HChange(value, to, 2520 new_value = new(zone()) HChange(value, to,
2575 is_truncating, deoptimize_on_undefined); 2521 is_truncating, deoptimize_on_undefined);
2576 } 2522 }
2577 2523
2578 new_value->InsertBefore(next); 2524 new_value->InsertBefore(next);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2618 if (phi->representation().IsInteger32()) { 2564 if (phi->representation().IsInteger32()) {
2619 phi->SetFlag(HValue::kTruncatingToInt32); 2565 phi->SetFlag(HValue::kTruncatingToInt32);
2620 } 2566 }
2621 } 2567 }
2622 bool change = true; 2568 bool change = true;
2623 while (change) { 2569 while (change) {
2624 change = false; 2570 change = false;
2625 for (int i = 0; i < phi_list()->length(); i++) { 2571 for (int i = 0; i < phi_list()->length(); i++) {
2626 HPhi* phi = phi_list()->at(i); 2572 HPhi* phi = phi_list()->at(i);
2627 if (!phi->CheckFlag(HValue::kTruncatingToInt32)) continue; 2573 if (!phi->CheckFlag(HValue::kTruncatingToInt32)) continue;
2628 if (!phi->CheckUsesForFlag(HValue::kTruncatingToInt32)) { 2574 for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) {
2629 phi->ClearFlag(HValue::kTruncatingToInt32); 2575 // If a Phi is used as a non-truncating int32 or as a double,
2630 change = true; 2576 // clear its "truncating" flag.
2577 HValue* use = it.value();
2578 Representation input_representation =
2579 use->RequiredInputRepresentation(it.index());
2580 if ((input_representation.IsInteger32() &&
2581 !use->CheckFlag(HValue::kTruncatingToInt32)) ||
2582 input_representation.IsDouble()) {
2583 if (FLAG_trace_representation) {
2584 PrintF("#%d Phi is not truncating because of #%d %s\n",
2585 phi->id(), it.value()->id(), it.value()->Mnemonic());
2586 }
2587 phi->ClearFlag(HValue::kTruncatingToInt32);
2588 change = true;
2589 break;
2590 }
2631 } 2591 }
2632 } 2592 }
2633 } 2593 }
2634 2594
2635 for (int i = 0; i < blocks_.length(); ++i) { 2595 for (int i = 0; i < blocks_.length(); ++i) {
2636 // Process phi instructions first. 2596 // Process phi instructions first.
2637 const ZoneList<HPhi*>* phis = blocks_[i]->phis(); 2597 const ZoneList<HPhi*>* phis = blocks_[i]->phis();
2638 for (int j = 0; j < phis->length(); j++) { 2598 for (int j = 0; j < phis->length(); j++) {
2639 InsertRepresentationChangesForValue(phis->at(j)); 2599 InsertRepresentationChangesForValue(phis->at(j));
2640 } 2600 }
2641 2601
2642 // Process normal instructions. 2602 // Process normal instructions.
2643 HInstruction* current = blocks_[i]->first(); 2603 HInstruction* current = blocks_[i]->first();
2644 while (current != NULL) { 2604 while (current != NULL) {
2605 HInstruction* next = current->next();
2645 InsertRepresentationChangesForValue(current); 2606 InsertRepresentationChangesForValue(current);
2646 current = current->next(); 2607 current = next;
2647 } 2608 }
2648 } 2609 }
2649 } 2610 }
2650 2611
2651 2612
2652 void HGraph::RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi* phi) { 2613 void HGraph::RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi* phi) {
2653 if (phi->CheckFlag(HValue::kDeoptimizeOnUndefined)) return; 2614 if (phi->CheckFlag(HValue::kDeoptimizeOnUndefined)) return;
2654 phi->SetFlag(HValue::kDeoptimizeOnUndefined); 2615 phi->SetFlag(HValue::kDeoptimizeOnUndefined);
2655 for (int i = 0; i < phi->OperandCount(); ++i) { 2616 for (int i = 0; i < phi->OperandCount(); ++i) {
2656 HValue* input = phi->OperandAt(i); 2617 HValue* input = phi->OperandAt(i);
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
3031 2992
3032 2993
3033 void TestContext::ReturnValue(HValue* value) { 2994 void TestContext::ReturnValue(HValue* value) {
3034 BuildBranch(value); 2995 BuildBranch(value);
3035 } 2996 }
3036 2997
3037 2998
3038 void EffectContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { 2999 void EffectContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
3039 ASSERT(!instr->IsControlInstruction()); 3000 ASSERT(!instr->IsControlInstruction());
3040 owner()->AddInstruction(instr); 3001 owner()->AddInstruction(instr);
3041 if (instr->HasObservableSideEffects()) owner()->AddSimulate(ast_id); 3002 if (instr->HasObservableSideEffects()) {
3003 owner()->AddSimulate(ast_id, REMOVABLE_SIMULATE);
3004 }
3042 } 3005 }
3043 3006
3044 3007
3045 void EffectContext::ReturnControl(HControlInstruction* instr, 3008 void EffectContext::ReturnControl(HControlInstruction* instr,
3046 BailoutId ast_id) { 3009 BailoutId ast_id) {
3047 ASSERT(!instr->HasObservableSideEffects()); 3010 ASSERT(!instr->HasObservableSideEffects());
3048 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); 3011 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock();
3049 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); 3012 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock();
3050 instr->SetSuccessorAt(0, empty_true); 3013 instr->SetSuccessorAt(0, empty_true);
3051 instr->SetSuccessorAt(1, empty_false); 3014 instr->SetSuccessorAt(1, empty_false);
3052 owner()->current_block()->Finish(instr); 3015 owner()->current_block()->Finish(instr);
3053 HBasicBlock* join = owner()->CreateJoin(empty_true, empty_false, ast_id); 3016 HBasicBlock* join = owner()->CreateJoin(empty_true, empty_false, ast_id);
3054 owner()->set_current_block(join); 3017 owner()->set_current_block(join);
3055 } 3018 }
3056 3019
3057 3020
3058 void ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { 3021 void ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
3059 ASSERT(!instr->IsControlInstruction()); 3022 ASSERT(!instr->IsControlInstruction());
3060 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { 3023 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) {
3061 return owner()->Bailout("bad value context for arguments object value"); 3024 return owner()->Bailout("bad value context for arguments object value");
3062 } 3025 }
3063 owner()->AddInstruction(instr); 3026 owner()->AddInstruction(instr);
3064 owner()->Push(instr); 3027 owner()->Push(instr);
3065 if (instr->HasObservableSideEffects()) owner()->AddSimulate(ast_id); 3028 if (instr->HasObservableSideEffects()) {
3029 owner()->AddSimulate(ast_id, REMOVABLE_SIMULATE);
3030 }
3066 } 3031 }
3067 3032
3068 3033
3069 void ValueContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { 3034 void ValueContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) {
3070 ASSERT(!instr->HasObservableSideEffects()); 3035 ASSERT(!instr->HasObservableSideEffects());
3071 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { 3036 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) {
3072 return owner()->Bailout("bad value context for arguments object value"); 3037 return owner()->Bailout("bad value context for arguments object value");
3073 } 3038 }
3074 HBasicBlock* materialize_false = owner()->graph()->CreateBasicBlock(); 3039 HBasicBlock* materialize_false = owner()->graph()->CreateBasicBlock();
3075 HBasicBlock* materialize_true = owner()->graph()->CreateBasicBlock(); 3040 HBasicBlock* materialize_true = owner()->graph()->CreateBasicBlock();
(...skipping 11 matching lines...) Expand all
3087 3052
3088 3053
3089 void TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { 3054 void TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
3090 ASSERT(!instr->IsControlInstruction()); 3055 ASSERT(!instr->IsControlInstruction());
3091 HGraphBuilder* builder = owner(); 3056 HGraphBuilder* builder = owner();
3092 builder->AddInstruction(instr); 3057 builder->AddInstruction(instr);
3093 // We expect a simulate after every expression with side effects, though 3058 // We expect a simulate after every expression with side effects, though
3094 // this one isn't actually needed (and wouldn't work if it were targeted). 3059 // this one isn't actually needed (and wouldn't work if it were targeted).
3095 if (instr->HasObservableSideEffects()) { 3060 if (instr->HasObservableSideEffects()) {
3096 builder->Push(instr); 3061 builder->Push(instr);
3097 builder->AddSimulate(ast_id); 3062 builder->AddSimulate(ast_id, REMOVABLE_SIMULATE);
3098 builder->Pop(); 3063 builder->Pop();
3099 } 3064 }
3100 BuildBranch(instr); 3065 BuildBranch(instr);
3101 } 3066 }
3102 3067
3103 3068
3104 void TestContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { 3069 void TestContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) {
3105 ASSERT(!instr->HasObservableSideEffects()); 3070 ASSERT(!instr->HasObservableSideEffects());
3106 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); 3071 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock();
3107 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); 3072 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock();
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
3314 const ZoneList<HPhi*>* phis = osr_loop_entry()->phis(); 3279 const ZoneList<HPhi*>* phis = osr_loop_entry()->phis();
3315 for (int j = 0; j < phis->length(); j++) { 3280 for (int j = 0; j < phis->length(); j++) {
3316 HPhi* phi = phis->at(j); 3281 HPhi* phi = phis->at(j);
3317 osr_values()->at(phi->merged_index())->set_incoming_value(phi); 3282 osr_values()->at(phi->merged_index())->set_incoming_value(phi);
3318 } 3283 }
3319 } 3284 }
3320 3285
3321 HInferRepresentation rep(this); 3286 HInferRepresentation rep(this);
3322 rep.Analyze(); 3287 rep.Analyze();
3323 3288
3289 // Remove HSimulate instructions that have turned out not to be needed
3290 // after all by folding them into the following HSimulate.
3291 // This must happen after inferring representations.
3292 MergeRemovableSimulates();
3293
3324 MarkDeoptimizeOnUndefined(); 3294 MarkDeoptimizeOnUndefined();
3325 InsertRepresentationChanges(); 3295 InsertRepresentationChanges();
3326 3296
3327 InitializeInferredTypes(); 3297 InitializeInferredTypes();
3328 3298
3329 // Must be performed before canonicalization to ensure that Canonicalize 3299 // Must be performed before canonicalization to ensure that Canonicalize
3330 // will not remove semantically meaningful ToInt32 operations e.g. BIT_OR with 3300 // will not remove semantically meaningful ToInt32 operations e.g. BIT_OR with
3331 // zero. 3301 // zero.
3332 ComputeSafeUint32Operations(); 3302 ComputeSafeUint32Operations();
3333 3303
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after
3803 } 3773 }
3804 3774
3805 3775
3806 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { 3776 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) {
3807 ASSERT(current_block() != NULL); 3777 ASSERT(current_block() != NULL);
3808 current_block()->AddInstruction(instr); 3778 current_block()->AddInstruction(instr);
3809 return instr; 3779 return instr;
3810 } 3780 }
3811 3781
3812 3782
3813 void HGraphBuilder::AddSimulate(BailoutId ast_id) { 3783 void HGraphBuilder::AddSimulate(BailoutId ast_id, RemovableSimulate removable) {
3814 ASSERT(current_block() != NULL); 3784 ASSERT(current_block() != NULL);
3815 current_block()->AddSimulate(ast_id); 3785 current_block()->AddSimulate(ast_id, removable);
3816 } 3786 }
3817 3787
3818 3788
3819 void HGraphBuilder::AddPhi(HPhi* instr) { 3789 void HGraphBuilder::AddPhi(HPhi* instr) {
3820 ASSERT(current_block() != NULL); 3790 ASSERT(current_block() != NULL);
3821 current_block()->AddPhi(instr); 3791 current_block()->AddPhi(instr);
3822 } 3792 }
3823 3793
3824 3794
3825 void HGraphBuilder::PushAndAdd(HInstruction* instr) { 3795 void HGraphBuilder::PushAndAdd(HInstruction* instr) {
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
4162 switch_type = SMI_SWITCH; 4132 switch_type = SMI_SWITCH;
4163 } else if (clause->label()->IsStringLiteral()) { 4133 } else if (clause->label()->IsStringLiteral()) {
4164 switch_type = STRING_SWITCH; 4134 switch_type = STRING_SWITCH;
4165 } else { 4135 } else {
4166 return Bailout("SwitchStatement: non-literal switch label"); 4136 return Bailout("SwitchStatement: non-literal switch label");
4167 } 4137 }
4168 } else if ((switch_type == STRING_SWITCH && 4138 } else if ((switch_type == STRING_SWITCH &&
4169 !clause->label()->IsStringLiteral()) || 4139 !clause->label()->IsStringLiteral()) ||
4170 (switch_type == SMI_SWITCH && 4140 (switch_type == SMI_SWITCH &&
4171 !clause->label()->IsSmiLiteral())) { 4141 !clause->label()->IsSmiLiteral())) {
4172 return Bailout("SwitchStatemnt: mixed label types are not supported"); 4142 return Bailout("SwitchStatement: mixed label types are not supported");
4173 } 4143 }
4174 } 4144 }
4175 4145
4176 HUnaryControlInstruction* string_check = NULL; 4146 HUnaryControlInstruction* string_check = NULL;
4177 HBasicBlock* not_string_block = NULL; 4147 HBasicBlock* not_string_block = NULL;
4178 4148
4179 // Test switch's tag value if all clauses are string literals 4149 // Test switch's tag value if all clauses are string literals
4180 if (switch_type == STRING_SWITCH) { 4150 if (switch_type == STRING_SWITCH) {
4181 string_check = new(zone()) HIsStringAndBranch(tag_value); 4151 string_check = new(zone()) HIsStringAndBranch(tag_value);
4182 first_test_block = graph()->CreateBasicBlock(); 4152 first_test_block = graph()->CreateBasicBlock();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
4216 // account for invisible uses. 4186 // account for invisible uses.
4217 current_block()->FinishExitWithDeoptimization(HDeoptimize::kUseAll); 4187 current_block()->FinishExitWithDeoptimization(HDeoptimize::kUseAll);
4218 set_current_block(NULL); 4188 set_current_block(NULL);
4219 break; 4189 break;
4220 } 4190 }
4221 4191
4222 HCompareIDAndBranch* compare_ = 4192 HCompareIDAndBranch* compare_ =
4223 new(zone()) HCompareIDAndBranch(tag_value, 4193 new(zone()) HCompareIDAndBranch(tag_value,
4224 label_value, 4194 label_value,
4225 Token::EQ_STRICT); 4195 Token::EQ_STRICT);
4226 compare_->SetInputRepresentation(Representation::Integer32()); 4196 compare_->set_observed_input_representation(
4197 Representation::Integer32(), Representation::Integer32());
4227 compare = compare_; 4198 compare = compare_;
4228 } else { 4199 } else {
4229 compare = new(zone()) HStringCompareAndBranch(context, tag_value, 4200 compare = new(zone()) HStringCompareAndBranch(context, tag_value,
4230 label_value, 4201 label_value,
4231 Token::EQ_STRICT); 4202 Token::EQ_STRICT);
4232 } 4203 }
4233 4204
4234 compare->SetSuccessorAt(0, body_block); 4205 compare->SetSuccessorAt(0, body_block);
4235 compare->SetSuccessorAt(1, next_test_block); 4206 compare->SetSuccessorAt(1, next_test_block);
4236 current_block()->Finish(compare); 4207 current_block()->Finish(compare);
4237 4208
4238 set_current_block(next_test_block); 4209 set_current_block(next_test_block);
4239 } 4210 }
4240 4211
4241 // Save the current block to use for the default or to join with the 4212 // Save the current block to use for the default or to join with the
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
4580 current_block()->Goto(loop_entry); 4551 current_block()->Goto(loop_entry);
4581 set_current_block(loop_entry); 4552 set_current_block(loop_entry);
4582 if (osr_entry) graph()->set_osr_loop_entry(loop_entry); 4553 if (osr_entry) graph()->set_osr_loop_entry(loop_entry);
4583 4554
4584 HValue* index = environment()->ExpressionStackAt(0); 4555 HValue* index = environment()->ExpressionStackAt(0);
4585 HValue* limit = environment()->ExpressionStackAt(1); 4556 HValue* limit = environment()->ExpressionStackAt(1);
4586 4557
4587 // Check that we still have more keys. 4558 // Check that we still have more keys.
4588 HCompareIDAndBranch* compare_index = 4559 HCompareIDAndBranch* compare_index =
4589 new(zone()) HCompareIDAndBranch(index, limit, Token::LT); 4560 new(zone()) HCompareIDAndBranch(index, limit, Token::LT);
4590 compare_index->SetInputRepresentation(Representation::Integer32()); 4561 compare_index->set_observed_input_representation(
4562 Representation::Integer32(), Representation::Integer32());
4591 4563
4592 HBasicBlock* loop_body = graph()->CreateBasicBlock(); 4564 HBasicBlock* loop_body = graph()->CreateBasicBlock();
4593 HBasicBlock* loop_successor = graph()->CreateBasicBlock(); 4565 HBasicBlock* loop_successor = graph()->CreateBasicBlock();
4594 4566
4595 compare_index->SetSuccessorAt(0, loop_body); 4567 compare_index->SetSuccessorAt(0, loop_body);
4596 compare_index->SetSuccessorAt(1, loop_successor); 4568 compare_index->SetSuccessorAt(1, loop_successor);
4597 current_block()->Finish(compare_index); 4569 current_block()->Finish(compare_index);
4598 4570
4599 set_current_block(loop_successor); 4571 set_current_block(loop_successor);
4600 Drop(5); 4572 Drop(5);
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
4855 return Bailout("reference to a variable which requires dynamic lookup"); 4827 return Bailout("reference to a variable which requires dynamic lookup");
4856 } 4828 }
4857 } 4829 }
4858 4830
4859 4831
4860 void HGraphBuilder::VisitLiteral(Literal* expr) { 4832 void HGraphBuilder::VisitLiteral(Literal* expr) {
4861 ASSERT(!HasStackOverflow()); 4833 ASSERT(!HasStackOverflow());
4862 ASSERT(current_block() != NULL); 4834 ASSERT(current_block() != NULL);
4863 ASSERT(current_block()->HasPredecessor()); 4835 ASSERT(current_block()->HasPredecessor());
4864 HConstant* instr = 4836 HConstant* instr =
4865 new(zone()) HConstant(expr->handle(), Representation::Tagged()); 4837 new(zone()) HConstant(expr->handle(), Representation::None());
4866 return ast_context()->ReturnInstruction(instr, expr->id()); 4838 return ast_context()->ReturnInstruction(instr, expr->id());
4867 } 4839 }
4868 4840
4869 4841
4870 void HGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { 4842 void HGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
4871 ASSERT(!HasStackOverflow()); 4843 ASSERT(!HasStackOverflow());
4872 ASSERT(current_block() != NULL); 4844 ASSERT(current_block() != NULL);
4873 ASSERT(current_block()->HasPredecessor()); 4845 ASSERT(current_block()->HasPredecessor());
4874 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); 4846 Handle<JSFunction> closure = function_state()->compilation_info()->closure();
4875 Handle<FixedArray> literals(closure->literals()); 4847 Handle<FixedArray> literals(closure->literals());
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
5092 Handle<JSFunction> setter; 5064 Handle<JSFunction> setter;
5093 Handle<JSObject> holder; 5065 Handle<JSObject> holder;
5094 ASSERT(!LookupSetter(map, name, &setter, &holder)); 5066 ASSERT(!LookupSetter(map, name, &setter, &holder));
5095 #endif 5067 #endif
5096 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(literal, 5068 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(literal,
5097 name, 5069 name,
5098 value, 5070 value,
5099 map)); 5071 map));
5100 } 5072 }
5101 AddInstruction(store); 5073 AddInstruction(store);
5102 if (store->HasObservableSideEffects()) AddSimulate(key->id()); 5074 if (store->HasObservableSideEffects()) {
5075 AddSimulate(key->id(), REMOVABLE_SIMULATE);
5076 }
5103 } else { 5077 } else {
5104 CHECK_ALIVE(VisitForEffect(value)); 5078 CHECK_ALIVE(VisitForEffect(value));
5105 } 5079 }
5106 break; 5080 break;
5107 } 5081 }
5108 // Fall through. 5082 // Fall through.
5109 case ObjectLiteral::Property::PROTOTYPE: 5083 case ObjectLiteral::Property::PROTOTYPE:
5110 case ObjectLiteral::Property::SETTER: 5084 case ObjectLiteral::Property::SETTER:
5111 case ObjectLiteral::Property::GETTER: 5085 case ObjectLiteral::Property::GETTER:
5112 return Bailout("Object literal with complex property"); 5086 return Bailout("Object literal with complex property");
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
5473 5447
5474 if (join != NULL) { 5448 if (join != NULL) {
5475 if (!ast_context()->IsEffect()) Push(value); 5449 if (!ast_context()->IsEffect()) Push(value);
5476 current_block()->Goto(join); 5450 current_block()->Goto(join);
5477 } else { 5451 } else {
5478 // The HSimulate for the store should not see the stored value in 5452 // The HSimulate for the store should not see the stored value in
5479 // effect contexts (it is not materialized at expr->id() in the 5453 // effect contexts (it is not materialized at expr->id() in the
5480 // unoptimized code). 5454 // unoptimized code).
5481 if (instr->HasObservableSideEffects()) { 5455 if (instr->HasObservableSideEffects()) {
5482 if (ast_context()->IsEffect()) { 5456 if (ast_context()->IsEffect()) {
5483 AddSimulate(expr->id()); 5457 AddSimulate(expr->id(), REMOVABLE_SIMULATE);
5484 } else { 5458 } else {
5485 Push(value); 5459 Push(value);
5486 AddSimulate(expr->id()); 5460 AddSimulate(expr->id(), REMOVABLE_SIMULATE);
5487 Drop(1); 5461 Drop(1);
5488 } 5462 }
5489 } 5463 }
5490 return ast_context()->ReturnValue(value); 5464 return ast_context()->ReturnValue(value);
5491 } 5465 }
5492 } 5466 }
5493 5467
5494 ASSERT(join != NULL); 5468 ASSERT(join != NULL);
5495 join->SetJoinId(expr->id()); 5469 join->SetJoinId(expr->id());
5496 set_current_block(join); 5470 set_current_block(join);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
5546 Drop(2); 5520 Drop(2);
5547 return HandlePolymorphicStoreNamedField(expr, object, value, types, name); 5521 return HandlePolymorphicStoreNamedField(expr, object, value, types, name);
5548 } else { 5522 } else {
5549 Drop(2); 5523 Drop(2);
5550 instr = BuildStoreNamedGeneric(object, name, value); 5524 instr = BuildStoreNamedGeneric(object, name, value);
5551 } 5525 }
5552 5526
5553 Push(value); 5527 Push(value);
5554 instr->set_position(expr->position()); 5528 instr->set_position(expr->position());
5555 AddInstruction(instr); 5529 AddInstruction(instr);
5556 if (instr->HasObservableSideEffects()) AddSimulate(expr->AssignmentId()); 5530 if (instr->HasObservableSideEffects()) {
5531 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
5532 }
5557 return ast_context()->ReturnValue(Pop()); 5533 return ast_context()->ReturnValue(Pop());
5558 5534
5559 } else { 5535 } else {
5560 // Keyed store. 5536 // Keyed store.
5561 CHECK_ALIVE(VisitForValue(prop->key())); 5537 CHECK_ALIVE(VisitForValue(prop->key()));
5562 CHECK_ALIVE(VisitForValue(expr->value())); 5538 CHECK_ALIVE(VisitForValue(expr->value()));
5563 HValue* value = Pop(); 5539 HValue* value = Pop();
5564 HValue* key = Pop(); 5540 HValue* key = Pop();
5565 HValue* object = Pop(); 5541 HValue* object = Pop();
5566 bool has_side_effects = false; 5542 bool has_side_effects = false;
5567 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(), 5543 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(),
5568 expr->position(), 5544 expr->position(),
5569 true, // is_store 5545 true, // is_store
5570 &has_side_effects); 5546 &has_side_effects);
5571 Push(value); 5547 Push(value);
5572 ASSERT(has_side_effects); // Stores always have side effects. 5548 ASSERT(has_side_effects); // Stores always have side effects.
5573 AddSimulate(expr->AssignmentId()); 5549 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
5574 return ast_context()->ReturnValue(Pop()); 5550 return ast_context()->ReturnValue(Pop());
5575 } 5551 }
5576 } 5552 }
5577 5553
5578 5554
5579 // Because not every expression has a position and there is not common 5555 // Because not every expression has a position and there is not common
5580 // superclass of Assignment and CountOperation, we cannot just pass the 5556 // superclass of Assignment and CountOperation, we cannot just pass the
5581 // owning expression instead of position and ast_id separately. 5557 // owning expression instead of position and ast_id separately.
5582 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, 5558 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var,
5583 HValue* value, 5559 HValue* value,
5584 int position, 5560 int position,
5585 BailoutId ast_id) { 5561 BailoutId ast_id) {
5586 LookupResult lookup(isolate()); 5562 LookupResult lookup(isolate());
5587 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); 5563 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true);
5588 if (type == kUseCell) { 5564 if (type == kUseCell) {
5589 Handle<GlobalObject> global(info()->global_object()); 5565 Handle<GlobalObject> global(info()->global_object());
5590 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); 5566 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup));
5591 HInstruction* instr = 5567 HInstruction* instr =
5592 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); 5568 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails());
5593 instr->set_position(position); 5569 instr->set_position(position);
5594 AddInstruction(instr); 5570 AddInstruction(instr);
5595 if (instr->HasObservableSideEffects()) AddSimulate(ast_id); 5571 if (instr->HasObservableSideEffects()) {
5572 AddSimulate(ast_id, REMOVABLE_SIMULATE);
5573 }
5596 } else { 5574 } else {
5597 HValue* context = environment()->LookupContext(); 5575 HValue* context = environment()->LookupContext();
5598 HGlobalObject* global_object = new(zone()) HGlobalObject(context); 5576 HGlobalObject* global_object = new(zone()) HGlobalObject(context);
5599 AddInstruction(global_object); 5577 AddInstruction(global_object);
5600 HStoreGlobalGeneric* instr = 5578 HStoreGlobalGeneric* instr =
5601 new(zone()) HStoreGlobalGeneric(context, 5579 new(zone()) HStoreGlobalGeneric(context,
5602 global_object, 5580 global_object,
5603 var->name(), 5581 var->name(),
5604 value, 5582 value,
5605 function_strict_mode_flag()); 5583 function_strict_mode_flag());
5606 instr->set_position(position); 5584 instr->set_position(position);
5607 AddInstruction(instr); 5585 AddInstruction(instr);
5608 ASSERT(instr->HasObservableSideEffects()); 5586 ASSERT(instr->HasObservableSideEffects());
5609 if (instr->HasObservableSideEffects()) AddSimulate(ast_id); 5587 AddSimulate(ast_id, REMOVABLE_SIMULATE);
5610 } 5588 }
5611 } 5589 }
5612 5590
5613 5591
5614 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { 5592 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
5615 Expression* target = expr->target(); 5593 Expression* target = expr->target();
5616 VariableProxy* proxy = target->AsVariableProxy(); 5594 VariableProxy* proxy = target->AsVariableProxy();
5617 Property* prop = target->AsProperty(); 5595 Property* prop = target->AsProperty();
5618 ASSERT(proxy == NULL || prop == NULL); 5596 ASSERT(proxy == NULL || prop == NULL);
5619 5597
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
5676 UNREACHABLE(); 5654 UNREACHABLE();
5677 default: 5655 default:
5678 mode = HStoreContextSlot::kNoCheck; 5656 mode = HStoreContextSlot::kNoCheck;
5679 } 5657 }
5680 5658
5681 HValue* context = BuildContextChainWalk(var); 5659 HValue* context = BuildContextChainWalk(var);
5682 HStoreContextSlot* instr = 5660 HStoreContextSlot* instr =
5683 new(zone()) HStoreContextSlot(context, var->index(), mode, Top()); 5661 new(zone()) HStoreContextSlot(context, var->index(), mode, Top());
5684 AddInstruction(instr); 5662 AddInstruction(instr);
5685 if (instr->HasObservableSideEffects()) { 5663 if (instr->HasObservableSideEffects()) {
5686 AddSimulate(expr->AssignmentId()); 5664 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
5687 } 5665 }
5688 break; 5666 break;
5689 } 5667 }
5690 5668
5691 case Variable::LOOKUP: 5669 case Variable::LOOKUP:
5692 return Bailout("compound assignment to lookup slot"); 5670 return Bailout("compound assignment to lookup slot");
5693 } 5671 }
5694 return ast_context()->ReturnValue(Pop()); 5672 return ast_context()->ReturnValue(Pop());
5695 5673
5696 } else if (prop != NULL) { 5674 } else if (prop != NULL) {
(...skipping 19 matching lines...) Expand all
5716 Handle<JSObject> holder; 5694 Handle<JSObject> holder;
5717 if (LookupGetter(map, name, &getter, &holder)) { 5695 if (LookupGetter(map, name, &getter, &holder)) {
5718 load = BuildCallGetter(object, map, getter, holder); 5696 load = BuildCallGetter(object, map, getter, holder);
5719 } else { 5697 } else {
5720 load = BuildLoadNamedMonomorphic(object, name, prop, map); 5698 load = BuildLoadNamedMonomorphic(object, name, prop, map);
5721 } 5699 }
5722 } else { 5700 } else {
5723 load = BuildLoadNamedGeneric(object, name, prop); 5701 load = BuildLoadNamedGeneric(object, name, prop);
5724 } 5702 }
5725 PushAndAdd(load); 5703 PushAndAdd(load);
5726 if (load->HasObservableSideEffects()) AddSimulate(prop->LoadId()); 5704 if (load->HasObservableSideEffects()) {
5705 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
5706 }
5727 5707
5728 CHECK_ALIVE(VisitForValue(expr->value())); 5708 CHECK_ALIVE(VisitForValue(expr->value()));
5729 HValue* right = Pop(); 5709 HValue* right = Pop();
5730 HValue* left = Pop(); 5710 HValue* left = Pop();
5731 5711
5732 HInstruction* instr = BuildBinaryOperation(operation, left, right); 5712 HInstruction* instr = BuildBinaryOperation(operation, left, right);
5733 PushAndAdd(instr); 5713 PushAndAdd(instr);
5734 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); 5714 if (instr->HasObservableSideEffects()) {
5715 AddSimulate(operation->id(), REMOVABLE_SIMULATE);
5716 }
5735 5717
5736 HInstruction* store; 5718 HInstruction* store;
5737 if (!monomorphic) { 5719 if (!monomorphic) {
5738 // If we don't know the monomorphic type, do a generic store. 5720 // If we don't know the monomorphic type, do a generic store.
5739 CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, instr)); 5721 CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, instr));
5740 } else { 5722 } else {
5741 Handle<JSFunction> setter; 5723 Handle<JSFunction> setter;
5742 Handle<JSObject> holder; 5724 Handle<JSObject> holder;
5743 if (LookupSetter(map, name, &setter, &holder)) { 5725 if (LookupSetter(map, name, &setter, &holder)) {
5744 store = BuildCallSetter(object, instr, map, setter, holder); 5726 store = BuildCallSetter(object, instr, map, setter, holder);
5745 } else { 5727 } else {
5746 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object, 5728 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object,
5747 name, 5729 name,
5748 instr, 5730 instr,
5749 map)); 5731 map));
5750 } 5732 }
5751 } 5733 }
5752 AddInstruction(store); 5734 AddInstruction(store);
5753 // Drop the simulated receiver and value. Return the value. 5735 // Drop the simulated receiver and value. Return the value.
5754 Drop(2); 5736 Drop(2);
5755 Push(instr); 5737 Push(instr);
5756 if (store->HasObservableSideEffects()) AddSimulate(expr->AssignmentId()); 5738 if (store->HasObservableSideEffects()) {
5739 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
5740 }
5757 return ast_context()->ReturnValue(Pop()); 5741 return ast_context()->ReturnValue(Pop());
5758 5742
5759 } else { 5743 } else {
5760 // Keyed property. 5744 // Keyed property.
5761 CHECK_ALIVE(VisitForValue(prop->obj())); 5745 CHECK_ALIVE(VisitForValue(prop->obj()));
5762 CHECK_ALIVE(VisitForValue(prop->key())); 5746 CHECK_ALIVE(VisitForValue(prop->key()));
5763 HValue* obj = environment()->ExpressionStackAt(1); 5747 HValue* obj = environment()->ExpressionStackAt(1);
5764 HValue* key = environment()->ExpressionStackAt(0); 5748 HValue* key = environment()->ExpressionStackAt(0);
5765 5749
5766 bool has_side_effects = false; 5750 bool has_side_effects = false;
5767 HValue* load = HandleKeyedElementAccess( 5751 HValue* load = HandleKeyedElementAccess(
5768 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition, 5752 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition,
5769 false, // is_store 5753 false, // is_store
5770 &has_side_effects); 5754 &has_side_effects);
5771 Push(load); 5755 Push(load);
5772 if (has_side_effects) AddSimulate(prop->LoadId()); 5756 if (has_side_effects) AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
5773 5757
5774 5758
5775 CHECK_ALIVE(VisitForValue(expr->value())); 5759 CHECK_ALIVE(VisitForValue(expr->value()));
5776 HValue* right = Pop(); 5760 HValue* right = Pop();
5777 HValue* left = Pop(); 5761 HValue* left = Pop();
5778 5762
5779 HInstruction* instr = BuildBinaryOperation(operation, left, right); 5763 HInstruction* instr = BuildBinaryOperation(operation, left, right);
5780 PushAndAdd(instr); 5764 PushAndAdd(instr);
5781 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); 5765 if (instr->HasObservableSideEffects()) {
5766 AddSimulate(operation->id(), REMOVABLE_SIMULATE);
5767 }
5782 5768
5783 expr->RecordTypeFeedback(oracle(), zone()); 5769 expr->RecordTypeFeedback(oracle(), zone());
5784 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(), 5770 HandleKeyedElementAccess(obj, key, instr, expr, expr->AssignmentId(),
5785 RelocInfo::kNoPosition, 5771 RelocInfo::kNoPosition,
5786 true, // is_store 5772 true, // is_store
5787 &has_side_effects); 5773 &has_side_effects);
5788 5774
5789 // Drop the simulated receiver, key, and value. Return the value. 5775 // Drop the simulated receiver, key, and value. Return the value.
5790 Drop(3); 5776 Drop(3);
5791 Push(instr); 5777 Push(instr);
5792 ASSERT(has_side_effects); // Stores always have side effects. 5778 ASSERT(has_side_effects); // Stores always have side effects.
5793 AddSimulate(expr->AssignmentId()); 5779 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
5794 return ast_context()->ReturnValue(Pop()); 5780 return ast_context()->ReturnValue(Pop());
5795 } 5781 }
5796 5782
5797 } else { 5783 } else {
5798 return Bailout("invalid lhs in compound assignment"); 5784 return Bailout("invalid lhs in compound assignment");
5799 } 5785 }
5800 } 5786 }
5801 5787
5802 5788
5803 void HGraphBuilder::VisitAssignment(Assignment* expr) { 5789 void HGraphBuilder::VisitAssignment(Assignment* expr) {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
5906 ASSERT(expr->op() == Token::INIT_CONST); 5892 ASSERT(expr->op() == Token::INIT_CONST);
5907 5893
5908 mode = HStoreContextSlot::kCheckIgnoreAssignment; 5894 mode = HStoreContextSlot::kCheckIgnoreAssignment;
5909 } 5895 }
5910 5896
5911 HValue* context = BuildContextChainWalk(var); 5897 HValue* context = BuildContextChainWalk(var);
5912 HStoreContextSlot* instr = new(zone()) HStoreContextSlot( 5898 HStoreContextSlot* instr = new(zone()) HStoreContextSlot(
5913 context, var->index(), mode, Top()); 5899 context, var->index(), mode, Top());
5914 AddInstruction(instr); 5900 AddInstruction(instr);
5915 if (instr->HasObservableSideEffects()) { 5901 if (instr->HasObservableSideEffects()) {
5916 AddSimulate(expr->AssignmentId()); 5902 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
5917 } 5903 }
5918 return ast_context()->ReturnValue(Pop()); 5904 return ast_context()->ReturnValue(Pop());
5919 } 5905 }
5920 5906
5921 case Variable::LOOKUP: 5907 case Variable::LOOKUP:
5922 return Bailout("assignment to LOOKUP variable"); 5908 return Bailout("assignment to LOOKUP variable");
5923 } 5909 }
5924 } else { 5910 } else {
5925 return Bailout("invalid left-hand side in assignment"); 5911 return Bailout("invalid left-hand side in assignment");
5926 } 5912 }
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
6044 case EXTERNAL_PIXEL_ELEMENTS: { 6030 case EXTERNAL_PIXEL_ELEMENTS: {
6045 val = AddInstruction(new(zone()) HClampToUint8(val)); 6031 val = AddInstruction(new(zone()) HClampToUint8(val));
6046 break; 6032 break;
6047 } 6033 }
6048 case EXTERNAL_BYTE_ELEMENTS: 6034 case EXTERNAL_BYTE_ELEMENTS:
6049 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 6035 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
6050 case EXTERNAL_SHORT_ELEMENTS: 6036 case EXTERNAL_SHORT_ELEMENTS:
6051 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 6037 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
6052 case EXTERNAL_INT_ELEMENTS: 6038 case EXTERNAL_INT_ELEMENTS:
6053 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { 6039 case EXTERNAL_UNSIGNED_INT_ELEMENTS: {
6054 if (!val->representation().IsInteger32()) {
6055 val = AddInstruction(new(zone()) HChange(
6056 val,
6057 Representation::Integer32(),
6058 true, // Truncate to int32.
6059 false)); // Don't deoptimize undefined (irrelevant here).
6060 }
6061 break; 6040 break;
6062 } 6041 }
6063 case EXTERNAL_FLOAT_ELEMENTS: 6042 case EXTERNAL_FLOAT_ELEMENTS:
6064 case EXTERNAL_DOUBLE_ELEMENTS: 6043 case EXTERNAL_DOUBLE_ELEMENTS:
6065 break; 6044 break;
6066 case FAST_SMI_ELEMENTS: 6045 case FAST_SMI_ELEMENTS:
6067 case FAST_ELEMENTS: 6046 case FAST_ELEMENTS:
6068 case FAST_DOUBLE_ELEMENTS: 6047 case FAST_DOUBLE_ELEMENTS:
6069 case FAST_HOLEY_SMI_ELEMENTS: 6048 case FAST_HOLEY_SMI_ELEMENTS:
6070 case FAST_HOLEY_ELEMENTS: 6049 case FAST_HOLEY_ELEMENTS:
(...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after
6671 HValue* key = Pop(); 6650 HValue* key = Pop();
6672 HValue* obj = Pop(); 6651 HValue* obj = Pop();
6673 6652
6674 bool has_side_effects = false; 6653 bool has_side_effects = false;
6675 HValue* load = HandleKeyedElementAccess( 6654 HValue* load = HandleKeyedElementAccess(
6676 obj, key, NULL, expr, expr->id(), expr->position(), 6655 obj, key, NULL, expr, expr->id(), expr->position(),
6677 false, // is_store 6656 false, // is_store
6678 &has_side_effects); 6657 &has_side_effects);
6679 if (has_side_effects) { 6658 if (has_side_effects) {
6680 if (ast_context()->IsEffect()) { 6659 if (ast_context()->IsEffect()) {
6681 AddSimulate(expr->id()); 6660 AddSimulate(expr->id(), REMOVABLE_SIMULATE);
6682 } else { 6661 } else {
6683 Push(load); 6662 Push(load);
6684 AddSimulate(expr->id()); 6663 AddSimulate(expr->id(), REMOVABLE_SIMULATE);
6685 Drop(1); 6664 Drop(1);
6686 } 6665 }
6687 } 6666 }
6688 return ast_context()->ReturnValue(load); 6667 return ast_context()->ReturnValue(load);
6689 } 6668 }
6690 instr->set_position(expr->position()); 6669 instr->set_position(expr->position());
6691 return ast_context()->ReturnInstruction(instr, expr->id()); 6670 return ast_context()->ReturnInstruction(instr, expr->id());
6692 } 6671 }
6693 6672
6694 6673
(...skipping 1228 matching lines...) Expand 10 before | Expand all | Expand 10 after
7923 } 7902 }
7924 7903
7925 7904
7926 void HGraphBuilder::VisitSub(UnaryOperation* expr) { 7905 void HGraphBuilder::VisitSub(UnaryOperation* expr) {
7927 CHECK_ALIVE(VisitForValue(expr->expression())); 7906 CHECK_ALIVE(VisitForValue(expr->expression()));
7928 HValue* value = Pop(); 7907 HValue* value = Pop();
7929 HValue* context = environment()->LookupContext(); 7908 HValue* context = environment()->LookupContext();
7930 HInstruction* instr = 7909 HInstruction* instr =
7931 new(zone()) HMul(context, value, graph_->GetConstantMinus1()); 7910 new(zone()) HMul(context, value, graph_->GetConstantMinus1());
7932 TypeInfo info = oracle()->UnaryType(expr); 7911 TypeInfo info = oracle()->UnaryType(expr);
7912 Representation rep = ToRepresentation(info);
7933 if (info.IsUninitialized()) { 7913 if (info.IsUninitialized()) {
7934 AddInstruction(new(zone()) HSoftDeoptimize); 7914 AddInstruction(new(zone()) HSoftDeoptimize);
7935 current_block()->MarkAsDeoptimizing(); 7915 current_block()->MarkAsDeoptimizing();
7936 info = TypeInfo::Unknown(); 7916 info = TypeInfo::Unknown();
7937 } 7917 }
7938 Representation rep = ToRepresentation(info); 7918 HBinaryOperation::cast(instr)->set_observed_input_representation(rep, rep);
7939 TraceRepresentation(expr->op(), info, instr, rep);
7940 instr->AssumeRepresentation(rep);
7941 return ast_context()->ReturnInstruction(instr, expr->id()); 7919 return ast_context()->ReturnInstruction(instr, expr->id());
7942 } 7920 }
7943 7921
7944 7922
7945 void HGraphBuilder::VisitBitNot(UnaryOperation* expr) { 7923 void HGraphBuilder::VisitBitNot(UnaryOperation* expr) {
7946 CHECK_ALIVE(VisitForValue(expr->expression())); 7924 CHECK_ALIVE(VisitForValue(expr->expression()));
7947 HValue* value = Pop(); 7925 HValue* value = Pop();
7948 TypeInfo info = oracle()->UnaryType(expr); 7926 TypeInfo info = oracle()->UnaryType(expr);
7949 if (info.IsUninitialized()) { 7927 if (info.IsUninitialized()) {
7950 AddInstruction(new(zone()) HSoftDeoptimize); 7928 AddInstruction(new(zone()) HSoftDeoptimize);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
8019 } 7997 }
8020 7998
8021 // The addition has no side effects, so we do not need 7999 // The addition has no side effects, so we do not need
8022 // to simulate the expression stack after this instruction. 8000 // to simulate the expression stack after this instruction.
8023 // Any later failures deopt to the load of the input or earlier. 8001 // Any later failures deopt to the load of the input or earlier.
8024 HConstant* delta = (expr->op() == Token::INC) 8002 HConstant* delta = (expr->op() == Token::INC)
8025 ? graph_->GetConstant1() 8003 ? graph_->GetConstant1()
8026 : graph_->GetConstantMinus1(); 8004 : graph_->GetConstantMinus1();
8027 HValue* context = environment()->LookupContext(); 8005 HValue* context = environment()->LookupContext();
8028 HInstruction* instr = new(zone()) HAdd(context, Top(), delta); 8006 HInstruction* instr = new(zone()) HAdd(context, Top(), delta);
8029 TraceRepresentation(expr->op(), info, instr, rep); 8007 // We can't insert a simulate here, because it would break deoptimization,
8008 // so the HAdd must not have side effects, so we must freeze its
8009 // representation.
8030 instr->AssumeRepresentation(rep); 8010 instr->AssumeRepresentation(rep);
8011 instr->ClearAllSideEffects();
8031 AddInstruction(instr); 8012 AddInstruction(instr);
8032 return instr; 8013 return instr;
8033 } 8014 }
8034 8015
8035 8016
8036 void HGraphBuilder::VisitCountOperation(CountOperation* expr) { 8017 void HGraphBuilder::VisitCountOperation(CountOperation* expr) {
8037 ASSERT(!HasStackOverflow()); 8018 ASSERT(!HasStackOverflow());
8038 ASSERT(current_block() != NULL); 8019 ASSERT(current_block() != NULL);
8039 ASSERT(current_block()->HasPredecessor()); 8020 ASSERT(current_block()->HasPredecessor());
8040 Expression* target = expr->expression(); 8021 Expression* target = expr->expression();
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
8094 } 8075 }
8095 } 8076 }
8096 8077
8097 HValue* context = BuildContextChainWalk(var); 8078 HValue* context = BuildContextChainWalk(var);
8098 HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode()) 8079 HStoreContextSlot::Mode mode = IsLexicalVariableMode(var->mode())
8099 ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck; 8080 ? HStoreContextSlot::kCheckDeoptimize : HStoreContextSlot::kNoCheck;
8100 HStoreContextSlot* instr = 8081 HStoreContextSlot* instr =
8101 new(zone()) HStoreContextSlot(context, var->index(), mode, after); 8082 new(zone()) HStoreContextSlot(context, var->index(), mode, after);
8102 AddInstruction(instr); 8083 AddInstruction(instr);
8103 if (instr->HasObservableSideEffects()) { 8084 if (instr->HasObservableSideEffects()) {
8104 AddSimulate(expr->AssignmentId()); 8085 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
8105 } 8086 }
8106 break; 8087 break;
8107 } 8088 }
8108 8089
8109 case Variable::LOOKUP: 8090 case Variable::LOOKUP:
8110 return Bailout("lookup variable in count operation"); 8091 return Bailout("lookup variable in count operation");
8111 } 8092 }
8112 8093
8113 } else { 8094 } else {
8114 // Argument of the count operation is a property. 8095 // Argument of the count operation is a property.
(...skipping 20 matching lines...) Expand all
8135 Handle<JSObject> holder; 8116 Handle<JSObject> holder;
8136 if (LookupGetter(map, name, &getter, &holder)) { 8117 if (LookupGetter(map, name, &getter, &holder)) {
8137 load = BuildCallGetter(object, map, getter, holder); 8118 load = BuildCallGetter(object, map, getter, holder);
8138 } else { 8119 } else {
8139 load = BuildLoadNamedMonomorphic(object, name, prop, map); 8120 load = BuildLoadNamedMonomorphic(object, name, prop, map);
8140 } 8121 }
8141 } else { 8122 } else {
8142 load = BuildLoadNamedGeneric(object, name, prop); 8123 load = BuildLoadNamedGeneric(object, name, prop);
8143 } 8124 }
8144 PushAndAdd(load); 8125 PushAndAdd(load);
8145 if (load->HasObservableSideEffects()) AddSimulate(prop->LoadId()); 8126 if (load->HasObservableSideEffects()) {
8127 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
8128 }
8146 8129
8147 after = BuildIncrement(returns_original_input, expr); 8130 after = BuildIncrement(returns_original_input, expr);
8148 input = Pop(); 8131 input = Pop();
8149 8132
8150 HInstruction* store; 8133 HInstruction* store;
8151 if (!monomorphic) { 8134 if (!monomorphic) {
8152 // If we don't know the monomorphic type, do a generic store. 8135 // If we don't know the monomorphic type, do a generic store.
8153 CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, after)); 8136 CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, after));
8154 } else { 8137 } else {
8155 Handle<JSFunction> setter; 8138 Handle<JSFunction> setter;
8156 Handle<JSObject> holder; 8139 Handle<JSObject> holder;
8157 if (LookupSetter(map, name, &setter, &holder)) { 8140 if (LookupSetter(map, name, &setter, &holder)) {
8158 store = BuildCallSetter(object, after, map, setter, holder); 8141 store = BuildCallSetter(object, after, map, setter, holder);
8159 } else { 8142 } else {
8160 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object, 8143 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object,
8161 name, 8144 name,
8162 after, 8145 after,
8163 map)); 8146 map));
8164 } 8147 }
8165 } 8148 }
8166 AddInstruction(store); 8149 AddInstruction(store);
8167 8150
8168 // Overwrite the receiver in the bailout environment with the result 8151 // Overwrite the receiver in the bailout environment with the result
8169 // of the operation, and the placeholder with the original value if 8152 // of the operation, and the placeholder with the original value if
8170 // necessary. 8153 // necessary.
8171 environment()->SetExpressionStackAt(0, after); 8154 environment()->SetExpressionStackAt(0, after);
8172 if (returns_original_input) environment()->SetExpressionStackAt(1, input); 8155 if (returns_original_input) environment()->SetExpressionStackAt(1, input);
8173 if (store->HasObservableSideEffects()) AddSimulate(expr->AssignmentId()); 8156 if (store->HasObservableSideEffects()) {
8157 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
8158 }
8174 8159
8175 } else { 8160 } else {
8176 // Keyed property. 8161 // Keyed property.
8177 if (returns_original_input) Push(graph_->GetConstantUndefined()); 8162 if (returns_original_input) Push(graph_->GetConstantUndefined());
8178 8163
8179 CHECK_ALIVE(VisitForValue(prop->obj())); 8164 CHECK_ALIVE(VisitForValue(prop->obj()));
8180 CHECK_ALIVE(VisitForValue(prop->key())); 8165 CHECK_ALIVE(VisitForValue(prop->key()));
8181 HValue* obj = environment()->ExpressionStackAt(1); 8166 HValue* obj = environment()->ExpressionStackAt(1);
8182 HValue* key = environment()->ExpressionStackAt(0); 8167 HValue* key = environment()->ExpressionStackAt(0);
8183 8168
8184 bool has_side_effects = false; 8169 bool has_side_effects = false;
8185 HValue* load = HandleKeyedElementAccess( 8170 HValue* load = HandleKeyedElementAccess(
8186 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition, 8171 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition,
8187 false, // is_store 8172 false, // is_store
8188 &has_side_effects); 8173 &has_side_effects);
8189 Push(load); 8174 Push(load);
8190 if (has_side_effects) AddSimulate(prop->LoadId()); 8175 if (has_side_effects) AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
8191 8176
8192 after = BuildIncrement(returns_original_input, expr); 8177 after = BuildIncrement(returns_original_input, expr);
8193 input = Pop(); 8178 input = Pop();
8194 8179
8195 expr->RecordTypeFeedback(oracle(), zone()); 8180 expr->RecordTypeFeedback(oracle(), zone());
8196 HandleKeyedElementAccess(obj, key, after, expr, expr->AssignmentId(), 8181 HandleKeyedElementAccess(obj, key, after, expr, expr->AssignmentId(),
8197 RelocInfo::kNoPosition, 8182 RelocInfo::kNoPosition,
8198 true, // is_store 8183 true, // is_store
8199 &has_side_effects); 8184 &has_side_effects);
8200 8185
8201 // Drop the key from the bailout environment. Overwrite the receiver 8186 // Drop the key from the bailout environment. Overwrite the receiver
8202 // with the result of the operation, and the placeholder with the 8187 // with the result of the operation, and the placeholder with the
8203 // original value if necessary. 8188 // original value if necessary.
8204 Drop(1); 8189 Drop(1);
8205 environment()->SetExpressionStackAt(0, after); 8190 environment()->SetExpressionStackAt(0, after);
8206 if (returns_original_input) environment()->SetExpressionStackAt(1, input); 8191 if (returns_original_input) environment()->SetExpressionStackAt(1, input);
8207 ASSERT(has_side_effects); // Stores always have side effects. 8192 ASSERT(has_side_effects); // Stores always have side effects.
8208 AddSimulate(expr->AssignmentId()); 8193 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
8209 } 8194 }
8210 } 8195 }
8211 8196
8212 Drop(returns_original_input ? 2 : 1); 8197 Drop(returns_original_input ? 2 : 1);
8213 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); 8198 return ast_context()->ReturnValue(expr->is_postfix() ? input : after);
8214 } 8199 }
8215 8200
8216 8201
8217 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* context, 8202 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* context,
8218 HValue* string, 8203 HValue* string,
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
8279 } 8264 }
8280 } 8265 }
8281 return true; 8266 return true;
8282 } 8267 }
8283 8268
8284 8269
8285 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, 8270 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr,
8286 HValue* left, 8271 HValue* left,
8287 HValue* right) { 8272 HValue* right) {
8288 HValue* context = environment()->LookupContext(); 8273 HValue* context = environment()->LookupContext();
8289 TypeInfo info = oracle()->BinaryType(expr); 8274 TypeInfo left_info, right_info, result_info, combined_info;
8290 if (info.IsUninitialized()) { 8275 oracle()->BinaryType(expr, &left_info, &right_info, &result_info);
8276 Representation left_rep = ToRepresentation(left_info);
8277 Representation right_rep = ToRepresentation(right_info);
8278 Representation result_rep = ToRepresentation(result_info);
8279 if (left_info.IsUninitialized()) {
8280 // Can't have initialized one but not the other.
8281 ASSERT(right_info.IsUninitialized());
8291 AddInstruction(new(zone()) HSoftDeoptimize); 8282 AddInstruction(new(zone()) HSoftDeoptimize);
8292 current_block()->MarkAsDeoptimizing(); 8283 current_block()->MarkAsDeoptimizing();
8293 info = TypeInfo::Unknown(); 8284 left_info = right_info = TypeInfo::Unknown();
8294 } 8285 }
8295 HInstruction* instr = NULL; 8286 HInstruction* instr = NULL;
8296 switch (expr->op()) { 8287 switch (expr->op()) {
8297 case Token::ADD: 8288 case Token::ADD:
8298 if (info.IsString()) { 8289 if (left_info.IsString() && right_info.IsString()) {
8299 AddInstruction(new(zone()) HCheckNonSmi(left)); 8290 AddInstruction(new(zone()) HCheckNonSmi(left));
8300 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); 8291 AddInstruction(HCheckInstanceType::NewIsString(left, zone()));
8301 AddInstruction(new(zone()) HCheckNonSmi(right)); 8292 AddInstruction(new(zone()) HCheckNonSmi(right));
8302 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); 8293 AddInstruction(HCheckInstanceType::NewIsString(right, zone()));
8303 instr = new(zone()) HStringAdd(context, left, right); 8294 instr = new(zone()) HStringAdd(context, left, right);
8304 } else { 8295 } else {
8305 instr = HAdd::NewHAdd(zone(), context, left, right); 8296 instr = HAdd::NewHAdd(zone(), context, left, right);
8306 } 8297 }
8307 break; 8298 break;
8308 case Token::SUB: 8299 case Token::SUB:
8309 instr = HSub::NewHSub(zone(), context, left, right); 8300 instr = HSub::NewHSub(zone(), context, left, right);
8310 break; 8301 break;
8311 case Token::MUL: 8302 case Token::MUL:
8312 instr = HMul::NewHMul(zone(), context, left, right); 8303 instr = HMul::NewHMul(zone(), context, left, right);
8313 break; 8304 break;
8314 case Token::MOD: 8305 case Token::MOD:
8315 instr = HMod::NewHMod(zone(), context, left, right); 8306 instr = HMod::NewHMod(zone(), context, left, right);
8316 break; 8307 break;
8317 case Token::DIV: 8308 case Token::DIV:
8318 instr = HDiv::NewHDiv(zone(), context, left, right); 8309 instr = HDiv::NewHDiv(zone(), context, left, right);
8319 break; 8310 break;
8320 case Token::BIT_XOR: 8311 case Token::BIT_XOR:
8321 case Token::BIT_AND: 8312 case Token::BIT_AND:
8322 instr = HBitwise::NewHBitwise(zone(), expr->op(), context, left, right); 8313 instr = HBitwise::NewHBitwise(zone(), expr->op(), context, left, right);
8323 break; 8314 break;
8324 case Token::BIT_OR: { 8315 case Token::BIT_OR: {
8325 HValue* operand, *shift_amount; 8316 HValue* operand, *shift_amount;
8326 if (info.IsInteger32() && 8317 if (left_info.IsInteger32() && right_info.IsInteger32() &&
8327 MatchRotateRight(left, right, &operand, &shift_amount)) { 8318 MatchRotateRight(left, right, &operand, &shift_amount)) {
8328 instr = new(zone()) HRor(context, operand, shift_amount); 8319 instr = new(zone()) HRor(context, operand, shift_amount);
8329 } else { 8320 } else {
8330 instr = HBitwise::NewHBitwise(zone(), expr->op(), context, left, right); 8321 instr = HBitwise::NewHBitwise(zone(), expr->op(), context, left, right);
8331 } 8322 }
8332 break; 8323 break;
8333 } 8324 }
8334 case Token::SAR: 8325 case Token::SAR:
8335 instr = HSar::NewHSar(zone(), context, left, right); 8326 instr = HSar::NewHSar(zone(), context, left, right);
8336 break; 8327 break;
8337 case Token::SHR: 8328 case Token::SHR:
8338 instr = HShr::NewHShr(zone(), context, left, right); 8329 instr = HShr::NewHShr(zone(), context, left, right);
8339 if (FLAG_opt_safe_uint32_operations && instr->IsShr() && 8330 if (FLAG_opt_safe_uint32_operations && instr->IsShr() &&
8340 CanBeZero(right)) { 8331 CanBeZero(right)) {
8341 graph()->RecordUint32Instruction(instr); 8332 graph()->RecordUint32Instruction(instr);
8342 } 8333 }
8343 break; 8334 break;
8344 case Token::SHL: 8335 case Token::SHL:
8345 instr = HShl::NewHShl(zone(), context, left, right); 8336 instr = HShl::NewHShl(zone(), context, left, right);
8346 break; 8337 break;
8347 default: 8338 default:
8348 UNREACHABLE(); 8339 UNREACHABLE();
8349 } 8340 }
8350 8341
8351 // If we hit an uninitialized binary op stub we will get type info 8342 if (instr->IsBinaryOperation()) {
8352 // for a smi operation. If one of the operands is a constant string 8343 HBinaryOperation* binop = HBinaryOperation::cast(instr);
8353 // do not generate code assuming it is a smi operation. 8344 binop->set_observed_input_representation(left_rep, right_rep);
8354 if (info.IsSmi() && 8345 binop->initialize_output_representation(result_rep);
8355 ((left->IsConstant() && HConstant::cast(left)->handle()->IsString()) ||
8356 (right->IsConstant() && HConstant::cast(right)->handle()->IsString()))) {
8357 return instr;
8358 } 8346 }
8359 Representation rep = ToRepresentation(info);
8360 // We only generate either int32 or generic tagged bitwise operations.
8361 if (instr->IsBitwiseBinaryOperation()) {
8362 HBitwiseBinaryOperation::cast(instr)->
8363 InitializeObservedInputRepresentation(rep);
8364 if (rep.IsDouble()) rep = Representation::Integer32();
8365 }
8366 TraceRepresentation(expr->op(), info, instr, rep);
8367 instr->AssumeRepresentation(rep);
8368 return instr; 8347 return instr;
8369 } 8348 }
8370 8349
8371 8350
8372 // Check for the form (%_ClassOf(foo) === 'BarClass'). 8351 // Check for the form (%_ClassOf(foo) === 'BarClass').
8373 static bool IsClassOfTest(CompareOperation* expr) { 8352 static bool IsClassOfTest(CompareOperation* expr) {
8374 if (expr->op() != Token::EQ_STRICT) return false; 8353 if (expr->op() != Token::EQ_STRICT) return false;
8375 CallRuntime* call = expr->left()->AsCallRuntime(); 8354 CallRuntime* call = expr->left()->AsCallRuntime();
8376 if (call == NULL) return false; 8355 if (call == NULL) return false;
8377 Literal* literal = expr->right()->AsLiteral(); 8356 Literal* literal = expr->right()->AsLiteral();
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
8501 CHECK_ALIVE(VisitForValue(expr->left())); 8480 CHECK_ALIVE(VisitForValue(expr->left()));
8502 CHECK_ALIVE(VisitForValue(expr->right())); 8481 CHECK_ALIVE(VisitForValue(expr->right()));
8503 HValue* right = Pop(); 8482 HValue* right = Pop();
8504 HValue* left = Pop(); 8483 HValue* left = Pop();
8505 HInstruction* instr = BuildBinaryOperation(expr, left, right); 8484 HInstruction* instr = BuildBinaryOperation(expr, left, right);
8506 instr->set_position(expr->position()); 8485 instr->set_position(expr->position());
8507 return ast_context()->ReturnInstruction(instr, expr->id()); 8486 return ast_context()->ReturnInstruction(instr, expr->id());
8508 } 8487 }
8509 8488
8510 8489
8511 void HGraphBuilder::TraceRepresentation(Token::Value op,
8512 TypeInfo info,
8513 HValue* value,
8514 Representation rep) {
8515 if (!FLAG_trace_representation) return;
8516 // TODO(svenpanne) Under which circumstances are we actually not flexible?
8517 // At first glance, this looks a bit weird...
8518 bool flexible = value->CheckFlag(HValue::kFlexibleRepresentation);
8519 PrintF("Operation %s has type info %s, %schange representation assumption "
8520 "for %s (ID %d) from %s to %s\n",
8521 Token::Name(op),
8522 info.ToString(),
8523 flexible ? "" : " DO NOT ",
8524 value->Mnemonic(),
8525 graph_->GetMaximumValueID(),
8526 value->representation().Mnemonic(),
8527 rep.Mnemonic());
8528 }
8529
8530
8531 Representation HGraphBuilder::ToRepresentation(TypeInfo info) { 8490 Representation HGraphBuilder::ToRepresentation(TypeInfo info) {
8491 if (info.IsUninitialized()) return Representation::None();
8532 if (info.IsSmi()) return Representation::Integer32(); 8492 if (info.IsSmi()) return Representation::Integer32();
8533 if (info.IsInteger32()) return Representation::Integer32(); 8493 if (info.IsInteger32()) return Representation::Integer32();
8534 if (info.IsDouble()) return Representation::Double(); 8494 if (info.IsDouble()) return Representation::Double();
8535 if (info.IsNumber()) return Representation::Double(); 8495 if (info.IsNumber()) return Representation::Double();
8536 return Representation::Tagged(); 8496 return Representation::Tagged();
8537 } 8497 }
8538 8498
8539 8499
8540 void HGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, 8500 void HGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr,
8541 HTypeof* typeof_expr, 8501 HTypeof* typeof_expr,
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
8619 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 8579 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
8620 HValue* value = Pop(); 8580 HValue* value = Pop();
8621 Literal* literal = expr->right()->AsLiteral(); 8581 Literal* literal = expr->right()->AsLiteral();
8622 Handle<String> rhs = Handle<String>::cast(literal->handle()); 8582 Handle<String> rhs = Handle<String>::cast(literal->handle());
8623 HClassOfTestAndBranch* instr = 8583 HClassOfTestAndBranch* instr =
8624 new(zone()) HClassOfTestAndBranch(value, rhs); 8584 new(zone()) HClassOfTestAndBranch(value, rhs);
8625 instr->set_position(expr->position()); 8585 instr->set_position(expr->position());
8626 return ast_context()->ReturnControl(instr, expr->id()); 8586 return ast_context()->ReturnControl(instr, expr->id());
8627 } 8587 }
8628 8588
8629 TypeInfo type_info = oracle()->CompareType(expr); 8589 TypeInfo left_type, right_type, overall_type_info;
8590 oracle()->CompareType(expr, &left_type, &right_type, &overall_type_info);
8591 Representation combined_rep = ToRepresentation(overall_type_info);
8592 Representation left_rep = ToRepresentation(left_type);
8593 Representation right_rep = ToRepresentation(right_type);
8630 // Check if this expression was ever executed according to type feedback. 8594 // Check if this expression was ever executed according to type feedback.
8631 // Note that for the special typeof/null/undefined cases we get unknown here. 8595 // Note that for the special typeof/null/undefined cases we get unknown here.
8632 if (type_info.IsUninitialized()) { 8596 if (overall_type_info.IsUninitialized()) {
8633 AddInstruction(new(zone()) HSoftDeoptimize); 8597 AddInstruction(new(zone()) HSoftDeoptimize);
8634 current_block()->MarkAsDeoptimizing(); 8598 current_block()->MarkAsDeoptimizing();
8635 type_info = TypeInfo::Unknown(); 8599 overall_type_info = left_type = right_type = TypeInfo::Unknown();
8636 } 8600 }
8637 8601
8638 CHECK_ALIVE(VisitForValue(expr->left())); 8602 CHECK_ALIVE(VisitForValue(expr->left()));
8639 CHECK_ALIVE(VisitForValue(expr->right())); 8603 CHECK_ALIVE(VisitForValue(expr->right()));
8640 8604
8641 HValue* context = environment()->LookupContext(); 8605 HValue* context = environment()->LookupContext();
8642 HValue* right = Pop(); 8606 HValue* right = Pop();
8643 HValue* left = Pop(); 8607 HValue* left = Pop();
8644 Token::Value op = expr->op(); 8608 Token::Value op = expr->op();
8645 8609
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
8697 AddInstruction(new(zone()) HCheckFunction(right, target)); 8661 AddInstruction(new(zone()) HCheckFunction(right, target));
8698 HInstanceOfKnownGlobal* result = 8662 HInstanceOfKnownGlobal* result =
8699 new(zone()) HInstanceOfKnownGlobal(context, left, target); 8663 new(zone()) HInstanceOfKnownGlobal(context, left, target);
8700 result->set_position(expr->position()); 8664 result->set_position(expr->position());
8701 return ast_context()->ReturnInstruction(result, expr->id()); 8665 return ast_context()->ReturnInstruction(result, expr->id());
8702 } 8666 }
8703 } else if (op == Token::IN) { 8667 } else if (op == Token::IN) {
8704 HIn* result = new(zone()) HIn(context, left, right); 8668 HIn* result = new(zone()) HIn(context, left, right);
8705 result->set_position(expr->position()); 8669 result->set_position(expr->position());
8706 return ast_context()->ReturnInstruction(result, expr->id()); 8670 return ast_context()->ReturnInstruction(result, expr->id());
8707 } else if (type_info.IsNonPrimitive()) { 8671 } else if (overall_type_info.IsNonPrimitive()) {
8708 switch (op) { 8672 switch (op) {
8709 case Token::EQ: 8673 case Token::EQ:
8710 case Token::EQ_STRICT: { 8674 case Token::EQ_STRICT: {
8711 // Can we get away with map check and not instance type check? 8675 // Can we get away with map check and not instance type check?
8712 Handle<Map> map = oracle()->GetCompareMap(expr); 8676 Handle<Map> map = oracle()->GetCompareMap(expr);
8713 if (!map.is_null()) { 8677 if (!map.is_null()) {
8714 AddCheckMapsWithTransitions(left, map); 8678 AddCheckMapsWithTransitions(left, map);
8715 AddCheckMapsWithTransitions(right, map); 8679 AddCheckMapsWithTransitions(right, map);
8716 HCompareObjectEqAndBranch* result = 8680 HCompareObjectEqAndBranch* result =
8717 new(zone()) HCompareObjectEqAndBranch(left, right); 8681 new(zone()) HCompareObjectEqAndBranch(left, right);
8718 result->set_position(expr->position()); 8682 result->set_position(expr->position());
8719 return ast_context()->ReturnControl(result, expr->id()); 8683 return ast_context()->ReturnControl(result, expr->id());
8720 } else { 8684 } else {
8721 AddInstruction(new(zone()) HCheckNonSmi(left)); 8685 AddInstruction(new(zone()) HCheckNonSmi(left));
8722 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone())); 8686 AddInstruction(HCheckInstanceType::NewIsSpecObject(left, zone()));
8723 AddInstruction(new(zone()) HCheckNonSmi(right)); 8687 AddInstruction(new(zone()) HCheckNonSmi(right));
8724 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone())); 8688 AddInstruction(HCheckInstanceType::NewIsSpecObject(right, zone()));
8725 HCompareObjectEqAndBranch* result = 8689 HCompareObjectEqAndBranch* result =
8726 new(zone()) HCompareObjectEqAndBranch(left, right); 8690 new(zone()) HCompareObjectEqAndBranch(left, right);
8727 result->set_position(expr->position()); 8691 result->set_position(expr->position());
8728 return ast_context()->ReturnControl(result, expr->id()); 8692 return ast_context()->ReturnControl(result, expr->id());
8729 } 8693 }
8730 } 8694 }
8731 default: 8695 default:
8732 return Bailout("Unsupported non-primitive compare"); 8696 return Bailout("Unsupported non-primitive compare");
8733 } 8697 }
8734 } else if (type_info.IsString() && oracle()->IsSymbolCompare(expr) && 8698 } else if (overall_type_info.IsSymbol() && Token::IsEqualityOp(op)) {
8735 (op == Token::EQ || op == Token::EQ_STRICT)) {
8736 AddInstruction(new(zone()) HCheckNonSmi(left)); 8699 AddInstruction(new(zone()) HCheckNonSmi(left));
8737 AddInstruction(HCheckInstanceType::NewIsSymbol(left, zone())); 8700 AddInstruction(HCheckInstanceType::NewIsSymbol(left, zone()));
8738 AddInstruction(new(zone()) HCheckNonSmi(right)); 8701 AddInstruction(new(zone()) HCheckNonSmi(right));
8739 AddInstruction(HCheckInstanceType::NewIsSymbol(right, zone())); 8702 AddInstruction(HCheckInstanceType::NewIsSymbol(right, zone()));
8740 HCompareObjectEqAndBranch* result = 8703 HCompareObjectEqAndBranch* result =
8741 new(zone()) HCompareObjectEqAndBranch(left, right); 8704 new(zone()) HCompareObjectEqAndBranch(left, right);
8742 result->set_position(expr->position()); 8705 result->set_position(expr->position());
8743 return ast_context()->ReturnControl(result, expr->id()); 8706 return ast_context()->ReturnControl(result, expr->id());
8744 } else { 8707 } else {
8745 Representation r = ToRepresentation(type_info); 8708 if (combined_rep.IsTagged() || combined_rep.IsNone()) {
8746 if (r.IsTagged()) {
8747 HCompareGeneric* result = 8709 HCompareGeneric* result =
8748 new(zone()) HCompareGeneric(context, left, right, op); 8710 new(zone()) HCompareGeneric(context, left, right, op);
8711 result->set_observed_input_representation(left_rep, right_rep);
8749 result->set_position(expr->position()); 8712 result->set_position(expr->position());
8750 return ast_context()->ReturnInstruction(result, expr->id()); 8713 return ast_context()->ReturnInstruction(result, expr->id());
8751 } else { 8714 } else {
8752 HCompareIDAndBranch* result = 8715 HCompareIDAndBranch* result =
8753 new(zone()) HCompareIDAndBranch(left, right, op); 8716 new(zone()) HCompareIDAndBranch(left, right, op);
8717 result->set_observed_input_representation(left_rep, right_rep);
8754 result->set_position(expr->position()); 8718 result->set_position(expr->position());
8755 result->SetInputRepresentation(r);
8756 return ast_context()->ReturnControl(result, expr->id()); 8719 return ast_context()->ReturnControl(result, expr->id());
8757 } 8720 }
8758 } 8721 }
8759 } 8722 }
8760 8723
8761 8724
8762 void HGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, 8725 void HGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr,
8763 HValue* value, 8726 HValue* value,
8764 NilValue nil) { 8727 NilValue nil) {
8765 ASSERT(!HasStackOverflow()); 8728 ASSERT(!HasStackOverflow());
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
8832 environment()->Bind(variable, value); 8795 environment()->Bind(variable, value);
8833 } 8796 }
8834 break; 8797 break;
8835 case Variable::CONTEXT: 8798 case Variable::CONTEXT:
8836 if (hole_init) { 8799 if (hole_init) {
8837 HValue* value = graph()->GetConstantHole(); 8800 HValue* value = graph()->GetConstantHole();
8838 HValue* context = environment()->LookupContext(); 8801 HValue* context = environment()->LookupContext();
8839 HStoreContextSlot* store = new(zone()) HStoreContextSlot( 8802 HStoreContextSlot* store = new(zone()) HStoreContextSlot(
8840 context, variable->index(), HStoreContextSlot::kNoCheck, value); 8803 context, variable->index(), HStoreContextSlot::kNoCheck, value);
8841 AddInstruction(store); 8804 AddInstruction(store);
8842 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); 8805 if (store->HasObservableSideEffects()) {
8806 AddSimulate(proxy->id(), REMOVABLE_SIMULATE);
8807 }
8843 } 8808 }
8844 break; 8809 break;
8845 case Variable::LOOKUP: 8810 case Variable::LOOKUP:
8846 return Bailout("unsupported lookup slot in declaration"); 8811 return Bailout("unsupported lookup slot in declaration");
8847 } 8812 }
8848 } 8813 }
8849 8814
8850 8815
8851 void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) { 8816 void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) {
8852 VariableProxy* proxy = declaration->proxy(); 8817 VariableProxy* proxy = declaration->proxy();
(...skipping 15 matching lines...) Expand all
8868 environment()->Bind(variable, value); 8833 environment()->Bind(variable, value);
8869 break; 8834 break;
8870 } 8835 }
8871 case Variable::CONTEXT: { 8836 case Variable::CONTEXT: {
8872 CHECK_ALIVE(VisitForValue(declaration->fun())); 8837 CHECK_ALIVE(VisitForValue(declaration->fun()));
8873 HValue* value = Pop(); 8838 HValue* value = Pop();
8874 HValue* context = environment()->LookupContext(); 8839 HValue* context = environment()->LookupContext();
8875 HStoreContextSlot* store = new(zone()) HStoreContextSlot( 8840 HStoreContextSlot* store = new(zone()) HStoreContextSlot(
8876 context, variable->index(), HStoreContextSlot::kNoCheck, value); 8841 context, variable->index(), HStoreContextSlot::kNoCheck, value);
8877 AddInstruction(store); 8842 AddInstruction(store);
8878 if (store->HasObservableSideEffects()) AddSimulate(proxy->id()); 8843 if (store->HasObservableSideEffects()) {
8844 AddSimulate(proxy->id(), REMOVABLE_SIMULATE);
8845 }
8879 break; 8846 break;
8880 } 8847 }
8881 case Variable::LOOKUP: 8848 case Variable::LOOKUP:
8882 return Bailout("unsupported lookup slot in declaration"); 8849 return Bailout("unsupported lookup slot in declaration");
8883 } 8850 }
8884 } 8851 }
8885 8852
8886 8853
8887 void HGraphBuilder::VisitModuleDeclaration(ModuleDeclaration* declaration) { 8854 void HGraphBuilder::VisitModuleDeclaration(ModuleDeclaration* declaration) {
8888 UNREACHABLE(); 8855 UNREACHABLE();
(...skipping 1122 matching lines...) Expand 10 before | Expand all | Expand 10 after
10011 } 9978 }
10012 } 9979 }
10013 9980
10014 #ifdef DEBUG 9981 #ifdef DEBUG
10015 if (graph_ != NULL) graph_->Verify(false); // No full verify. 9982 if (graph_ != NULL) graph_->Verify(false); // No full verify.
10016 if (allocator_ != NULL) allocator_->Verify(); 9983 if (allocator_ != NULL) allocator_->Verify();
10017 #endif 9984 #endif
10018 } 9985 }
10019 9986
10020 } } // namespace v8::internal 9987 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698