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

Side by Side Diff: src/hydrogen.cc

Issue 16948005: Refactor turning polymorphic loads into monomorphic loads (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments Created 7 years, 6 months 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') | no next file » | 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 6298 matching lines...) Expand 10 before | Expand all | Expand 10 after
6309 if (ComputeLoadStoreField(map, name, &lookup, true)) { 6309 if (ComputeLoadStoreField(map, name, &lookup, true)) {
6310 AddCheckMapsWithTransitions(object, map); 6310 AddCheckMapsWithTransitions(object, map);
6311 return BuildStoreNamedField(object, name, value, map, &lookup); 6311 return BuildStoreNamedField(object, name, value, map, &lookup);
6312 } 6312 }
6313 6313
6314 // No luck, do a generic store. 6314 // No luck, do a generic store.
6315 return BuildStoreNamedGeneric(object, name, value); 6315 return BuildStoreNamedGeneric(object, name, value);
6316 } 6316 }
6317 6317
6318 6318
6319 bool HOptimizedGraphBuilder::HandlePolymorphicArrayLengthLoad( 6319 HInstruction* HOptimizedGraphBuilder::TryLoadPolymorphicAsMonomorphic(
6320 Property* expr, 6320 Property* expr,
6321 HValue* object, 6321 HValue* object,
6322 SmallMapList* types, 6322 SmallMapList* types,
6323 Handle<String> name) { 6323 Handle<String> name) {
6324 if (!name->Equals(isolate()->heap()->length_string())) return false;
6325
6326 for (int i = 0; i < types->length(); i++) {
6327 if (types->at(i)->instance_type() != JS_ARRAY_TYPE) return false;
6328 }
6329
6330 BuildCheckNonSmi(object);
6331
6332 HInstruction* typecheck =
6333 AddInstruction(HCheckMaps::New(object, types, zone()));
6334 HInstruction* instr = new(zone())
6335 HLoadNamedField(object, HObjectAccess::ForArrayLength(), typecheck);
6336
6337 instr->set_position(expr->position());
6338 ast_context()->ReturnInstruction(instr, expr->id());
6339 return true;
6340 }
6341
6342
6343 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr,
6344 HValue* object,
6345 SmallMapList* types,
6346 Handle<String> name) {
6347
6348 if (HandlePolymorphicArrayLengthLoad(expr, object, types, name))
6349 return;
6350
6351 BuildCheckNonSmi(object);
6352
6353 // Use monomorphic load if property lookup results in the same field index 6324 // Use monomorphic load if property lookup results in the same field index
6354 // for all maps. Requires special map check on the set of all handled maps. 6325 // for all maps. Requires special map check on the set of all handled maps.
6355 HInstruction* instr = NULL;
6356 LookupResult lookup(isolate()); 6326 LookupResult lookup(isolate());
6357 int count; 6327 int count;
6358 Representation representation = Representation::None(); 6328 Representation representation = Representation::None();
6359 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused. 6329 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused.
6360 for (count = 0; 6330 for (count = 0;
6361 count < types->length() && count < kMaxLoadPolymorphism; 6331 count < types->length() && count < kMaxLoadPolymorphism;
6362 ++count) { 6332 ++count) {
6363 Handle<Map> map = types->at(count); 6333 Handle<Map> map = types->at(count);
6364 if (!ComputeLoadStoreField(map, name, &lookup, false)) break; 6334 if (!ComputeLoadStoreField(map, name, &lookup, false)) break;
6365 6335
(...skipping 10 matching lines...) Expand all
6376 break; 6346 break;
6377 } else if (access.offset() != new_access.offset()) { 6347 } else if (access.offset() != new_access.offset()) {
6378 // Offsets did not match. 6348 // Offsets did not match.
6379 break; 6349 break;
6380 } else if (access.IsInobject() != new_access.IsInobject()) { 6350 } else if (access.IsInobject() != new_access.IsInobject()) {
6381 // In-objectness did not match. 6351 // In-objectness did not match.
6382 break; 6352 break;
6383 } 6353 }
6384 } 6354 }
6385 6355
6386 if (count == types->length()) { 6356 if (count != types->length()) return NULL;
6387 // Everything matched; can use monomorphic load. 6357
6388 AddInstruction(HCheckMaps::New(object, types, zone())); 6358 // Everything matched; can use monomorphic load.
6389 instr = BuildLoadNamedField(object, access, representation); 6359 BuildCheckNonSmi(object);
6390 } else { 6360 AddInstruction(HCheckMaps::New(object, types, zone()));
6361 return BuildLoadNamedField(object, access, representation);
6362 }
6363
6364
6365 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(
6366 Property* expr,
6367 HValue* object,
6368 SmallMapList* types,
6369 Handle<String> name) {
6370 HInstruction* instr = TryLoadPolymorphicAsMonomorphic(
6371 expr, object, types, name);
6372 if (instr == NULL) {
6391 // Something did not match; must use a polymorphic load. 6373 // Something did not match; must use a polymorphic load.
6374 BuildCheckNonSmi(object);
6392 HValue* context = environment()->LookupContext(); 6375 HValue* context = environment()->LookupContext();
6393 instr = new(zone()) HLoadNamedFieldPolymorphic( 6376 instr = new(zone()) HLoadNamedFieldPolymorphic(
6394 context, object, types, name, zone()); 6377 context, object, types, name, zone());
6395 } 6378 }
6396 6379
6397 instr->set_position(expr->position()); 6380 instr->set_position(expr->position());
6398 return ast_context()->ReturnInstruction(instr, expr->id()); 6381 return ast_context()->ReturnInstruction(instr, expr->id());
6399 } 6382 }
6400 6383
6401 6384
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
6676 return ast_context()->ReturnValue(Pop()); 6659 return ast_context()->ReturnValue(Pop());
6677 6660
6678 } else if (prop != NULL) { 6661 } else if (prop != NULL) {
6679 if (prop->key()->IsPropertyName()) { 6662 if (prop->key()->IsPropertyName()) {
6680 // Named property. 6663 // Named property.
6681 CHECK_ALIVE(VisitForValue(prop->obj())); 6664 CHECK_ALIVE(VisitForValue(prop->obj()));
6682 HValue* object = Top(); 6665 HValue* object = Top();
6683 6666
6684 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 6667 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
6685 Handle<Map> map; 6668 Handle<Map> map;
6686 HInstruction* load; 6669 HInstruction* load = NULL;
6670 SmallMapList* types = prop->GetReceiverTypes();
6687 bool monomorphic = prop->IsMonomorphic(); 6671 bool monomorphic = prop->IsMonomorphic();
6688 if (monomorphic) { 6672 if (monomorphic) {
6689 map = prop->GetReceiverTypes()->first(); 6673 map = types->first();
6690 // We can't generate code for a monomorphic dict mode load so 6674 // We can't generate code for a monomorphic dict mode load so
6691 // just pretend it is not monomorphic. 6675 // just pretend it is not monomorphic.
6692 if (map->is_dictionary_map()) monomorphic = false; 6676 if (map->is_dictionary_map()) monomorphic = false;
6693 } 6677 }
6694 if (monomorphic) { 6678 if (monomorphic) {
6695 Handle<JSFunction> getter; 6679 Handle<JSFunction> getter;
6696 Handle<JSObject> holder; 6680 Handle<JSObject> holder;
6697 if (LookupGetter(map, name, &getter, &holder)) { 6681 if (LookupGetter(map, name, &getter, &holder)) {
6698 load = BuildCallGetter(object, map, getter, holder); 6682 load = BuildCallGetter(object, map, getter, holder);
6699 } else { 6683 } else {
6700 load = BuildLoadNamedMonomorphic(object, name, prop, map); 6684 load = BuildLoadNamedMonomorphic(object, name, prop, map);
6701 } 6685 }
6702 } else { 6686 } else if (types != NULL && types->length() > 1) {
6703 load = BuildLoadNamedGeneric(object, name, prop); 6687 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name);
6704 } 6688 }
6689 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop);
6705 PushAndAdd(load); 6690 PushAndAdd(load);
6706 if (load->HasObservableSideEffects()) { 6691 if (load->HasObservableSideEffects()) {
6707 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 6692 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
6708 } 6693 }
6709 6694
6710 CHECK_ALIVE(VisitForValue(expr->value())); 6695 CHECK_ALIVE(VisitForValue(expr->value()));
6711 HValue* right = Pop(); 6696 HValue* right = Pop();
6712 HValue* left = Pop(); 6697 HValue* left = Pop();
6713 6698
6714 HInstruction* instr = BuildBinaryOperation(operation, left, right); 6699 HInstruction* instr = BuildBinaryOperation(operation, left, right);
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
6960 return field; 6945 return field;
6961 } 6946 }
6962 6947
6963 6948
6964 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( 6949 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric(
6965 HValue* object, 6950 HValue* object,
6966 Handle<String> name, 6951 Handle<String> name,
6967 Property* expr) { 6952 Property* expr) {
6968 if (expr->IsUninitialized()) { 6953 if (expr->IsUninitialized()) {
6969 AddSoftDeoptimize(); 6954 AddSoftDeoptimize();
6955 } else {
6956 // OS::DebugBreak();
6970 } 6957 }
6971 HValue* context = environment()->LookupContext(); 6958 HValue* context = environment()->LookupContext();
6972 return new(zone()) HLoadNamedGeneric(context, object, name); 6959 return new(zone()) HLoadNamedGeneric(context, object, name);
6973 } 6960 }
6974 6961
6975 6962
6976 HInstruction* HOptimizedGraphBuilder::BuildCallGetter( 6963 HInstruction* HOptimizedGraphBuilder::BuildCallGetter(
6977 HValue* object, 6964 HValue* object,
6978 Handle<Map> map, 6965 Handle<Map> map,
6979 Handle<JSFunction> getter, 6966 Handle<JSFunction> getter,
(...skipping 2278 matching lines...) Expand 10 before | Expand all | Expand 10 after
9258 9245
9259 if (prop->key()->IsPropertyName()) { 9246 if (prop->key()->IsPropertyName()) {
9260 // Named property. 9247 // Named property.
9261 if (returns_original_input) Push(graph()->GetConstantUndefined()); 9248 if (returns_original_input) Push(graph()->GetConstantUndefined());
9262 9249
9263 CHECK_ALIVE(VisitForValue(prop->obj())); 9250 CHECK_ALIVE(VisitForValue(prop->obj()));
9264 HValue* object = Top(); 9251 HValue* object = Top();
9265 9252
9266 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 9253 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
9267 Handle<Map> map; 9254 Handle<Map> map;
9268 HInstruction* load; 9255 HInstruction* load = NULL;
9269 bool monomorphic = prop->IsMonomorphic(); 9256 bool monomorphic = prop->IsMonomorphic();
9257 SmallMapList* types = prop->GetReceiverTypes();
9270 if (monomorphic) { 9258 if (monomorphic) {
9271 map = prop->GetReceiverTypes()->first(); 9259 map = types->first();
9272 if (map->is_dictionary_map()) monomorphic = false; 9260 if (map->is_dictionary_map()) monomorphic = false;
9273 } 9261 }
9274 if (monomorphic) { 9262 if (monomorphic) {
9275 Handle<JSFunction> getter; 9263 Handle<JSFunction> getter;
9276 Handle<JSObject> holder; 9264 Handle<JSObject> holder;
9277 if (LookupGetter(map, name, &getter, &holder)) { 9265 if (LookupGetter(map, name, &getter, &holder)) {
9278 load = BuildCallGetter(object, map, getter, holder); 9266 load = BuildCallGetter(object, map, getter, holder);
9279 } else { 9267 } else {
9280 load = BuildLoadNamedMonomorphic(object, name, prop, map); 9268 load = BuildLoadNamedMonomorphic(object, name, prop, map);
9281 } 9269 }
9282 } else { 9270 } else if (types != NULL && types->length() > 1) {
9283 load = BuildLoadNamedGeneric(object, name, prop); 9271 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name);
9284 } 9272 }
9273 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop);
9285 PushAndAdd(load); 9274 PushAndAdd(load);
9286 if (load->HasObservableSideEffects()) { 9275 if (load->HasObservableSideEffects()) {
9287 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 9276 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
9288 } 9277 }
9289 9278
9290 after = BuildIncrement(returns_original_input, expr); 9279 after = BuildIncrement(returns_original_input, expr);
9291 input = Pop(); 9280 input = Pop();
9292 9281
9293 HInstruction* store; 9282 HInstruction* store;
9294 if (!monomorphic || map->is_observed()) { 9283 if (!monomorphic || map->is_observed()) {
(...skipping 2319 matching lines...) Expand 10 before | Expand all | Expand 10 after
11614 } 11603 }
11615 } 11604 }
11616 11605
11617 #ifdef DEBUG 11606 #ifdef DEBUG
11618 if (graph_ != NULL) graph_->Verify(false); // No full verify. 11607 if (graph_ != NULL) graph_->Verify(false); // No full verify.
11619 if (allocator_ != NULL) allocator_->Verify(); 11608 if (allocator_ != NULL) allocator_->Verify();
11620 #endif 11609 #endif
11621 } 11610 }
11622 11611
11623 } } // namespace v8::internal 11612 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698