OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 4923 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4934 if (ComputeLoadStoreField(map, name, &lookup, true)) { | 4934 if (ComputeLoadStoreField(map, name, &lookup, true)) { |
4935 AddCheckMapsWithTransitions(object, map); | 4935 AddCheckMapsWithTransitions(object, map); |
4936 return BuildStoreNamedField(object, name, value, map, &lookup); | 4936 return BuildStoreNamedField(object, name, value, map, &lookup); |
4937 } | 4937 } |
4938 | 4938 |
4939 // No luck, do a generic store. | 4939 // No luck, do a generic store. |
4940 return BuildStoreNamedGeneric(object, name, value); | 4940 return BuildStoreNamedGeneric(object, name, value); |
4941 } | 4941 } |
4942 | 4942 |
4943 | 4943 |
4944 static bool CanLoadPropertyFromPrototype(Handle<Map> map, | |
4945 Handle<Name> name, | |
4946 LookupResult* lookup) { | |
4947 if (map->has_named_interceptor()) return false; | |
4948 if (map->is_dictionary_map()) return false; | |
4949 map->LookupDescriptor(NULL, *name, lookup); | |
4950 if (lookup->IsFound()) return false; | |
4951 return true; | |
4952 } | |
4953 | |
4954 | |
4944 HInstruction* HOptimizedGraphBuilder::TryLoadPolymorphicAsMonomorphic( | 4955 HInstruction* HOptimizedGraphBuilder::TryLoadPolymorphicAsMonomorphic( |
4945 Property* expr, | 4956 Property* expr, |
4946 HValue* object, | 4957 HValue* object, |
4947 SmallMapList* types, | 4958 SmallMapList* types, |
4948 Handle<String> name) { | 4959 Handle<String> name) { |
4949 // Use monomorphic load if property lookup results in the same field index | 4960 // Use monomorphic load if property lookup results in the same field index |
4950 // for all maps. Requires special map check on the set of all handled maps. | 4961 // for all maps. Requires special map check on the set of all handled maps. |
4951 if (types->length() > kMaxLoadPolymorphism) return NULL; | 4962 if (types->length() > kMaxLoadPolymorphism) return NULL; |
4952 | 4963 |
4953 LookupResult lookup(isolate()); | 4964 LookupResult lookup(isolate()); |
(...skipping 29 matching lines...) Expand all Loading... | |
4983 BuildCheckHeapObject(object); | 4994 BuildCheckHeapObject(object); |
4984 AddInstruction(HCheckMaps::New(object, types, zone())); | 4995 AddInstruction(HCheckMaps::New(object, types, zone())); |
4985 return BuildLoadNamedField(object, access, representation); | 4996 return BuildLoadNamedField(object, access, representation); |
4986 } | 4997 } |
4987 | 4998 |
4988 if (count != 0) return NULL; | 4999 if (count != 0) return NULL; |
4989 | 5000 |
4990 // Second chance: the property is on the prototype and all maps have the | 5001 // Second chance: the property is on the prototype and all maps have the |
4991 // same prototype. | 5002 // same prototype. |
4992 Handle<Map> map(types->at(0)); | 5003 Handle<Map> map(types->at(0)); |
4993 if (map->has_named_interceptor()) return NULL; | 5004 if (!CanLoadPropertyFromPrototype(map, name, &lookup)) return NULL; |
4994 if (map->is_dictionary_map()) return NULL; | |
4995 | 5005 |
4996 Handle<Object> prototype(map->prototype(), isolate()); | 5006 Handle<Object> prototype(map->prototype(), isolate()); |
4997 for (count = 1; count < types->length(); ++count) { | 5007 for (count = 1; count < types->length(); ++count) { |
4998 Handle<Map> test_map(types->at(count)); | 5008 Handle<Map> test_map(types->at(count)); |
4999 // Ensure the property is on the prototype, not the object itself. | 5009 if (!CanLoadPropertyFromPrototype(test_map, name, &lookup)) return NULL; |
5000 if (map->has_named_interceptor()) return NULL; | |
5001 if (test_map->is_dictionary_map()) return NULL; | |
5002 test_map->LookupDescriptor(NULL, *name, &lookup); | |
5003 if (lookup.IsFound()) return NULL; | |
5004 if (test_map->prototype() != *prototype) return NULL; | 5010 if (test_map->prototype() != *prototype) return NULL; |
5005 } | 5011 } |
5006 | 5012 |
5007 LookupInPrototypes(map, name, &lookup); | 5013 LookupInPrototypes(map, name, &lookup); |
5008 if (!lookup.IsField()) return NULL; | 5014 if (!lookup.IsField()) return NULL; |
5009 | 5015 |
5010 BuildCheckHeapObject(object); | 5016 BuildCheckHeapObject(object); |
5011 AddInstruction(HCheckMaps::New(object, types, zone())); | 5017 AddInstruction(HCheckMaps::New(object, types, zone())); |
5012 Handle<JSObject> holder(lookup.holder()); | 5018 Handle<JSObject> holder(lookup.holder()); |
5013 Handle<Map> holder_map(holder->map()); | 5019 Handle<Map> holder_map(holder->map()); |
(...skipping 1337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6351 | 6357 |
6352 inline bool operator<(const FunctionSorter& lhs, const FunctionSorter& rhs) { | 6358 inline bool operator<(const FunctionSorter& lhs, const FunctionSorter& rhs) { |
6353 int diff = lhs.ticks() - rhs.ticks(); | 6359 int diff = lhs.ticks() - rhs.ticks(); |
6354 if (diff != 0) return diff > 0; | 6360 if (diff != 0) return diff > 0; |
6355 diff = lhs.ast_length() - rhs.ast_length(); | 6361 diff = lhs.ast_length() - rhs.ast_length(); |
6356 if (diff != 0) return diff < 0; | 6362 if (diff != 0) return diff < 0; |
6357 return lhs.src_length() < rhs.src_length(); | 6363 return lhs.src_length() < rhs.src_length(); |
6358 } | 6364 } |
6359 | 6365 |
6360 | 6366 |
6367 bool HOptimizedGraphBuilder::TryCallPolymorphicAsMonomorphic( | |
6368 Call* expr, | |
6369 HValue* receiver, | |
6370 SmallMapList* types, | |
6371 Handle<String> name) { | |
6372 if (types->length() > kMaxCallPolymorphism) return false; | |
6373 | |
6374 Handle<Map> map(types->at(0)); | |
6375 LookupResult lookup(isolate()); | |
6376 if (!CanLoadPropertyFromPrototype(map, name, &lookup)) return false; | |
6377 | |
6378 Handle<Object> prototype(map->prototype(), isolate()); | |
6379 for (int count = 1; count < types->length(); ++count) { | |
6380 Handle<Map> test_map(types->at(count)); | |
6381 if (!CanLoadPropertyFromPrototype(test_map, name, &lookup)) return false; | |
6382 if (test_map->prototype() != *prototype) return false; | |
6383 } | |
6384 | |
6385 if (!expr->ComputeTarget(map, name)) return false; | |
6386 | |
6387 BuildCheckHeapObject(receiver); | |
6388 AddInstruction(HCheckMaps::New(receiver, types, zone())); | |
6389 AddCheckPrototypeMaps(expr->holder(), map); | |
6390 if (FLAG_trace_inlining) { | |
6391 Handle<JSFunction> caller = current_info()->closure(); | |
6392 SmartArrayPointer<char> caller_name = | |
6393 caller->shared()->DebugName()->ToCString(); | |
6394 PrintF("Trying to inline the polymorphic call to %s from %s\n", | |
6395 *name->ToCString(), *caller_name); | |
6396 } | |
6397 | |
6398 if (!TryInlineCall(expr)) { | |
6399 int argument_count = expr->arguments()->length() + 1; // Includes receiver. | |
6400 HCallConstantFunction* call = | |
6401 new(zone()) HCallConstantFunction(expr->target(), argument_count); | |
6402 call->set_position(expr->position()); | |
6403 PreProcessCall(call); | |
6404 AddInstruction(call); | |
6405 if (!ast_context()->IsEffect()) Push(call); | |
mvstanton
2013/07/10 12:48:14
Could you explain what is happening with this ast_
Toon Verwaest
2013/07/10 13:04:03
This is boilerplate code that's all over. I'll jus
| |
6406 AddSimulate(expr->id(), REMOVABLE_SIMULATE); | |
6407 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); | |
6408 } | |
6409 | |
6410 return true; | |
6411 } | |
6412 | |
6413 | |
6361 void HOptimizedGraphBuilder::HandlePolymorphicCallNamed( | 6414 void HOptimizedGraphBuilder::HandlePolymorphicCallNamed( |
6362 Call* expr, | 6415 Call* expr, |
6363 HValue* receiver, | 6416 HValue* receiver, |
6364 SmallMapList* types, | 6417 SmallMapList* types, |
6365 Handle<String> name) { | 6418 Handle<String> name) { |
6366 // TODO(ager): We should recognize when the prototype chains for different | 6419 if (TryCallPolymorphicAsMonomorphic(expr, receiver, types, name)) return; |
6367 // maps are identical. In that case we can avoid repeatedly generating the | 6420 |
6368 // same prototype map checks. | |
6369 int argument_count = expr->arguments()->length() + 1; // Includes receiver. | 6421 int argument_count = expr->arguments()->length() + 1; // Includes receiver. |
6370 HBasicBlock* join = NULL; | 6422 HBasicBlock* join = NULL; |
6371 FunctionSorter order[kMaxCallPolymorphism]; | 6423 FunctionSorter order[kMaxCallPolymorphism]; |
6372 int ordered_functions = 0; | 6424 int ordered_functions = 0; |
6373 | 6425 |
6374 Handle<Map> initial_string_map( | 6426 Handle<Map> initial_string_map( |
6375 isolate()->native_context()->string_function()->initial_map()); | 6427 isolate()->native_context()->string_function()->initial_map()); |
6376 Handle<Map> string_marker_map( | 6428 Handle<Map> string_marker_map( |
6377 JSObject::cast(initial_string_map->prototype())->map()); | 6429 JSObject::cast(initial_string_map->prototype())->map()); |
6378 Handle<Map> initial_number_map( | 6430 Handle<Map> initial_number_map( |
(...skipping 3795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10174 if (ShouldProduceTraceOutput()) { | 10226 if (ShouldProduceTraceOutput()) { |
10175 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10227 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
10176 } | 10228 } |
10177 | 10229 |
10178 #ifdef DEBUG | 10230 #ifdef DEBUG |
10179 graph_->Verify(false); // No full verify. | 10231 graph_->Verify(false); // No full verify. |
10180 #endif | 10232 #endif |
10181 } | 10233 } |
10182 | 10234 |
10183 } } // namespace v8::internal | 10235 } } // namespace v8::internal |
OLD | NEW |