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

Side by Side Diff: src/hydrogen.cc

Issue 10831153: Improve load IC so it can call a native accessor even if the holder is (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 8 years, 4 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
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 5197 matching lines...) Expand 10 before | Expand all | Expand 10 after
5208 CHECK_ALIVE(VisitForValue(expr->value())); 5208 CHECK_ALIVE(VisitForValue(expr->value()));
5209 HValue* value = environment()->ExpressionStackAt(0); 5209 HValue* value = environment()->ExpressionStackAt(0);
5210 HValue* object = environment()->ExpressionStackAt(1); 5210 HValue* object = environment()->ExpressionStackAt(1);
5211 5211
5212 Literal* key = prop->key()->AsLiteral(); 5212 Literal* key = prop->key()->AsLiteral();
5213 Handle<String> name = Handle<String>::cast(key->handle()); 5213 Handle<String> name = Handle<String>::cast(key->handle());
5214 ASSERT(!name.is_null()); 5214 ASSERT(!name.is_null());
5215 5215
5216 HInstruction* instr = NULL; 5216 HInstruction* instr = NULL;
5217 SmallMapList* types = expr->GetReceiverTypes(); 5217 SmallMapList* types = expr->GetReceiverTypes();
5218 if (expr->IsMonomorphic()) { 5218 bool monomorphic = expr->IsMonomorphic();
5219 Handle<Map> map = types->first(); 5219 Handle<Map> map;
5220 if (monomorphic) {
5221 map = types->first();
5222 if (map->is_dictionary_map()) monomorphic = false;
5223 }
5224 if (monomorphic) {
5220 Handle<AccessorPair> accessors; 5225 Handle<AccessorPair> accessors;
5221 Handle<JSObject> holder; 5226 Handle<JSObject> holder;
5222 if (LookupAccessorPair(map, name, &accessors, &holder)) { 5227 if (LookupAccessorPair(map, name, &accessors, &holder)) {
5223 Drop(2); 5228 Drop(2);
5224 instr = BuildCallSetter(object, value, map, accessors, holder); 5229 instr = BuildCallSetter(object, value, map, accessors, holder);
5225 } else { 5230 } else {
5226 Drop(2); 5231 Drop(2);
5227 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, 5232 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object,
5228 name, 5233 name,
5229 value, 5234 value,
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
5385 prop->RecordTypeFeedback(oracle(), zone()); 5390 prop->RecordTypeFeedback(oracle(), zone());
5386 5391
5387 if (prop->key()->IsPropertyName()) { 5392 if (prop->key()->IsPropertyName()) {
5388 // Named property. 5393 // Named property.
5389 CHECK_ALIVE(VisitForValue(prop->obj())); 5394 CHECK_ALIVE(VisitForValue(prop->obj()));
5390 HValue* object = Top(); 5395 HValue* object = Top();
5391 5396
5392 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 5397 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
5393 Handle<Map> map; 5398 Handle<Map> map;
5394 HInstruction* load; 5399 HInstruction* load;
5395 if (prop->IsMonomorphic()) { 5400 bool monomorphic = prop->IsMonomorphic();
5401 if (monomorphic) {
5396 map = prop->GetReceiverTypes()->first(); 5402 map = prop->GetReceiverTypes()->first();
5403 // We can't generate code for a monomorphic dict mode load so
5404 // just pretend it is not monomorphic.
5405 if (map->is_dictionary_map()) monomorphic = false;
5406 }
5407 if (monomorphic) {
5397 Handle<AccessorPair> accessors; 5408 Handle<AccessorPair> accessors;
5398 Handle<JSObject> holder; 5409 Handle<JSObject> holder;
5399 if (LookupAccessorPair(map, name, &accessors, &holder)) { 5410 if (LookupAccessorPair(map, name, &accessors, &holder)) {
5400 load = BuildCallGetter(object, map, accessors, holder); 5411 load = BuildCallGetter(object, map, accessors, holder);
5401 } else { 5412 } else {
5402 load = BuildLoadNamedMonomorphic(object, name, prop, map); 5413 load = BuildLoadNamedMonomorphic(object, name, prop, map);
5403 } 5414 }
5404 } else { 5415 } else {
5405 load = BuildLoadNamedGeneric(object, name, prop); 5416 load = BuildLoadNamedGeneric(object, name, prop);
5406 } 5417 }
5407 PushAndAdd(load); 5418 PushAndAdd(load);
5408 if (load->HasObservableSideEffects()) AddSimulate(expr->CompoundLoadId()); 5419 if (load->HasObservableSideEffects()) AddSimulate(expr->CompoundLoadId());
5409 5420
5410 CHECK_ALIVE(VisitForValue(expr->value())); 5421 CHECK_ALIVE(VisitForValue(expr->value()));
5411 HValue* right = Pop(); 5422 HValue* right = Pop();
5412 HValue* left = Pop(); 5423 HValue* left = Pop();
5413 5424
5414 HInstruction* instr = BuildBinaryOperation(operation, left, right); 5425 HInstruction* instr = BuildBinaryOperation(operation, left, right);
5415 PushAndAdd(instr); 5426 PushAndAdd(instr);
5416 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); 5427 if (instr->HasObservableSideEffects()) AddSimulate(operation->id());
5417 5428
5418 HInstruction* store; 5429 HInstruction* store;
5419 if (map.is_null()) { 5430 if (!monomorphic) {
5420 // If we don't know the monomorphic type, do a generic store. 5431 // If we don't know the monomorphic type, do a generic store.
5421 CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, instr)); 5432 CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, instr));
5422 } else { 5433 } else {
5423 Handle<AccessorPair> accessors; 5434 Handle<AccessorPair> accessors;
5424 Handle<JSObject> holder; 5435 Handle<JSObject> holder;
5425 // Because we re-use the load type feedback, there might be no setter. 5436 // Because we re-use the load type feedback, there might be no setter.
5426 if (LookupAccessorPair(map, name, &accessors, &holder) && 5437 if (LookupAccessorPair(map, name, &accessors, &holder) &&
5427 accessors->setter()->IsJSFunction()) { 5438 accessors->setter()->IsJSFunction()) {
5428 store = BuildCallSetter(object, instr, map, accessors, holder); 5439 store = BuildCallSetter(object, instr, map, accessors, holder);
5429 } else { 5440 } else {
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
5710 // We haven't found a JavaScript accessor anywhere. 5721 // We haven't found a JavaScript accessor anywhere.
5711 return false; 5722 return false;
5712 } 5723 }
5713 5724
5714 5725
5715 HInstruction* HGraphBuilder::BuildLoadNamedMonomorphic(HValue* object, 5726 HInstruction* HGraphBuilder::BuildLoadNamedMonomorphic(HValue* object,
5716 Handle<String> name, 5727 Handle<String> name,
5717 Property* expr, 5728 Property* expr,
5718 Handle<Map> map) { 5729 Handle<Map> map) {
5719 // Handle a load from a known field. 5730 // Handle a load from a known field.
5731 ASSERT(!map->is_dictionary_map());
5720 LookupResult lookup(isolate()); 5732 LookupResult lookup(isolate());
5721 map->LookupDescriptor(NULL, *name, &lookup); 5733 map->LookupDescriptor(NULL, *name, &lookup);
5722 if (lookup.IsField()) { 5734 if (lookup.IsField()) {
5723 return BuildLoadNamedField(object, map, &lookup, true); 5735 return BuildLoadNamedField(object, map, &lookup, true);
5724 } 5736 }
5725 5737
5726 // Handle a load of a constant known function. 5738 // Handle a load of a constant known function.
5727 if (lookup.IsConstantFunction()) { 5739 if (lookup.IsConstantFunction()) {
5728 AddInstruction(new(zone()) HCheckNonSmi(object)); 5740 AddInstruction(new(zone()) HCheckNonSmi(object));
5729 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone())); 5741 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone()));
(...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after
6343 6355
6344 } else if (expr->IsFunctionPrototype()) { 6356 } else if (expr->IsFunctionPrototype()) {
6345 HValue* function = Pop(); 6357 HValue* function = Pop();
6346 AddInstruction(new(zone()) HCheckNonSmi(function)); 6358 AddInstruction(new(zone()) HCheckNonSmi(function));
6347 instr = new(zone()) HLoadFunctionPrototype(function); 6359 instr = new(zone()) HLoadFunctionPrototype(function);
6348 6360
6349 } else if (expr->key()->IsPropertyName()) { 6361 } else if (expr->key()->IsPropertyName()) {
6350 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 6362 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
6351 SmallMapList* types = expr->GetReceiverTypes(); 6363 SmallMapList* types = expr->GetReceiverTypes();
6352 6364
6365 bool monomorphic = expr->IsMonomorphic();
6366 Handle<Map> map;
6353 if (expr->IsMonomorphic()) { 6367 if (expr->IsMonomorphic()) {
6354 Handle<Map> map = types->first(); 6368 map = types->first();
6369 if (map->is_dictionary_map()) monomorphic = false;
6370 }
6371 if (monomorphic) {
6355 Handle<AccessorPair> accessors; 6372 Handle<AccessorPair> accessors;
6356 Handle<JSObject> holder; 6373 Handle<JSObject> holder;
6357 if (LookupAccessorPair(map, name, &accessors, &holder)) { 6374 if (LookupAccessorPair(map, name, &accessors, &holder)) {
6358 AddCheckConstantFunction(holder, Top(), map, true); 6375 AddCheckConstantFunction(holder, Top(), map, true);
6359 Handle<JSFunction> getter(JSFunction::cast(accessors->getter())); 6376 Handle<JSFunction> getter(JSFunction::cast(accessors->getter()));
6360 if (FLAG_inline_accessors && TryInlineGetter(getter, expr)) return; 6377 if (FLAG_inline_accessors && TryInlineGetter(getter, expr)) return;
6361 AddInstruction(new(zone()) HPushArgument(Pop())); 6378 AddInstruction(new(zone()) HPushArgument(Pop()));
6362 instr = new(zone()) HCallConstantFunction(getter, 1); 6379 instr = new(zone()) HCallConstantFunction(getter, 1);
6363 } else { 6380 } else {
6364 instr = BuildLoadNamedMonomorphic(Pop(), name, expr, map); 6381 instr = BuildLoadNamedMonomorphic(Pop(), name, expr, map);
(...skipping 1488 matching lines...) Expand 10 before | Expand all | Expand 10 after
7853 if (prop->key()->IsPropertyName()) { 7870 if (prop->key()->IsPropertyName()) {
7854 // Named property. 7871 // Named property.
7855 if (returns_original_input) Push(graph_->GetConstantUndefined()); 7872 if (returns_original_input) Push(graph_->GetConstantUndefined());
7856 7873
7857 CHECK_ALIVE(VisitForValue(prop->obj())); 7874 CHECK_ALIVE(VisitForValue(prop->obj()));
7858 HValue* object = Top(); 7875 HValue* object = Top();
7859 7876
7860 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 7877 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
7861 Handle<Map> map; 7878 Handle<Map> map;
7862 HInstruction* load; 7879 HInstruction* load;
7863 if (prop->IsMonomorphic()) { 7880 bool monomorphic = prop->IsMonomorphic();
7881 if (monomorphic) {
7864 map = prop->GetReceiverTypes()->first(); 7882 map = prop->GetReceiverTypes()->first();
7883 if (map->is_dictionary_map()) monomorphic = false;
7884 }
7885 if (monomorphic) {
7865 Handle<AccessorPair> accessors; 7886 Handle<AccessorPair> accessors;
7866 Handle<JSObject> holder; 7887 Handle<JSObject> holder;
7867 if (LookupAccessorPair(map, name, &accessors, &holder)) { 7888 if (LookupAccessorPair(map, name, &accessors, &holder)) {
7868 load = BuildCallGetter(object, map, accessors, holder); 7889 load = BuildCallGetter(object, map, accessors, holder);
7869 } else { 7890 } else {
7870 load = BuildLoadNamedMonomorphic(object, name, prop, map); 7891 load = BuildLoadNamedMonomorphic(object, name, prop, map);
7871 } 7892 }
7872 } else { 7893 } else {
7873 load = BuildLoadNamedGeneric(object, name, prop); 7894 load = BuildLoadNamedGeneric(object, name, prop);
7874 } 7895 }
7875 PushAndAdd(load); 7896 PushAndAdd(load);
7876 if (load->HasObservableSideEffects()) AddSimulate(expr->CountId()); 7897 if (load->HasObservableSideEffects()) AddSimulate(expr->CountId());
7877 7898
7878 after = BuildIncrement(returns_original_input, expr); 7899 after = BuildIncrement(returns_original_input, expr);
7879 input = Pop(); 7900 input = Pop();
7880 7901
7881 HInstruction* store; 7902 HInstruction* store;
7882 if (map.is_null()) { 7903 if (!monomorphic) {
7883 // If we don't know the monomorphic type, do a generic store. 7904 // If we don't know the monomorphic type, do a generic store.
7884 CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, after)); 7905 CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, after));
7885 } else { 7906 } else {
7886 Handle<AccessorPair> accessors; 7907 Handle<AccessorPair> accessors;
7887 Handle<JSObject> holder; 7908 Handle<JSObject> holder;
7888 // Because we re-use the load type feedback, there might be no setter. 7909 // Because we re-use the load type feedback, there might be no setter.
7889 if (LookupAccessorPair(map, name, &accessors, &holder) && 7910 if (LookupAccessorPair(map, name, &accessors, &holder) &&
7890 accessors->setter()->IsJSFunction()) { 7911 accessors->setter()->IsJSFunction()) {
7891 store = BuildCallSetter(object, after, map, accessors, holder); 7912 store = BuildCallSetter(object, after, map, accessors, holder);
7892 } else { 7913 } else {
(...skipping 1771 matching lines...) Expand 10 before | Expand all | Expand 10 after
9664 } 9685 }
9665 } 9686 }
9666 9687
9667 #ifdef DEBUG 9688 #ifdef DEBUG
9668 if (graph_ != NULL) graph_->Verify(false); // No full verify. 9689 if (graph_ != NULL) graph_->Verify(false); // No full verify.
9669 if (allocator_ != NULL) allocator_->Verify(); 9690 if (allocator_ != NULL) allocator_->Verify();
9670 #endif 9691 #endif
9671 } 9692 }
9672 9693
9673 } } // namespace v8::internal 9694 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698