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

Side by Side Diff: src/hydrogen.cc

Issue 7655017: Improve memory usage of receiver type feedback. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: ReceiverTypeList -> SmallMapList Created 9 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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 3377 matching lines...) Expand 10 before | Expand all | Expand 10 after
3388 HValue* value, 3388 HValue* value,
3389 Expression* expr) { 3389 Expression* expr) {
3390 Property* prop = (expr->AsProperty() != NULL) 3390 Property* prop = (expr->AsProperty() != NULL)
3391 ? expr->AsProperty() 3391 ? expr->AsProperty()
3392 : expr->AsAssignment()->target()->AsProperty(); 3392 : expr->AsAssignment()->target()->AsProperty();
3393 Literal* key = prop->key()->AsLiteral(); 3393 Literal* key = prop->key()->AsLiteral();
3394 Handle<String> name = Handle<String>::cast(key->handle()); 3394 Handle<String> name = Handle<String>::cast(key->handle());
3395 ASSERT(!name.is_null()); 3395 ASSERT(!name.is_null());
3396 3396
3397 LookupResult lookup; 3397 LookupResult lookup;
3398 ZoneMapList* types = expr->GetReceiverTypes(); 3398 SmallMapList* types = expr->GetReceiverTypes();
3399 bool is_monomorphic = expr->IsMonomorphic() && 3399 bool is_monomorphic = expr->IsMonomorphic() &&
3400 ComputeStoredField(types->first(), name, &lookup); 3400 ComputeStoredField(types->first(), name, &lookup);
3401 3401
3402 return is_monomorphic 3402 return is_monomorphic
3403 ? BuildStoreNamedField(object, name, value, types->first(), &lookup, 3403 ? BuildStoreNamedField(object, name, value, types->first(), &lookup,
3404 true) // Needs smi and map check. 3404 true) // Needs smi and map check.
3405 : BuildStoreNamedGeneric(object, name, value); 3405 : BuildStoreNamedGeneric(object, name, value);
3406 } 3406 }
3407 3407
3408 3408
3409 void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, 3409 void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr,
3410 HValue* object, 3410 HValue* object,
3411 HValue* value, 3411 HValue* value,
3412 ZoneMapList* types, 3412 SmallMapList* types,
3413 Handle<String> name) { 3413 Handle<String> name) {
3414 // TODO(ager): We should recognize when the prototype chains for different 3414 // TODO(ager): We should recognize when the prototype chains for different
3415 // maps are identical. In that case we can avoid repeatedly generating the 3415 // maps are identical. In that case we can avoid repeatedly generating the
3416 // same prototype map checks. 3416 // same prototype map checks.
3417 int count = 0; 3417 int count = 0;
3418 HBasicBlock* join = NULL; 3418 HBasicBlock* join = NULL;
3419 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { 3419 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) {
3420 Handle<Map> map = types->at(i); 3420 Handle<Map> map = types->at(i);
3421 LookupResult lookup; 3421 LookupResult lookup;
3422 if (ComputeStoredField(map, name, &lookup)) { 3422 if (ComputeStoredField(map, name, &lookup)) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
3493 if (prop->key()->IsPropertyName()) { 3493 if (prop->key()->IsPropertyName()) {
3494 // Named store. 3494 // Named store.
3495 CHECK_ALIVE(VisitForValue(expr->value())); 3495 CHECK_ALIVE(VisitForValue(expr->value()));
3496 value = Pop(); 3496 value = Pop();
3497 HValue* object = Pop(); 3497 HValue* object = Pop();
3498 3498
3499 Literal* key = prop->key()->AsLiteral(); 3499 Literal* key = prop->key()->AsLiteral();
3500 Handle<String> name = Handle<String>::cast(key->handle()); 3500 Handle<String> name = Handle<String>::cast(key->handle());
3501 ASSERT(!name.is_null()); 3501 ASSERT(!name.is_null());
3502 3502
3503 ZoneMapList* types = expr->GetReceiverTypes(); 3503 SmallMapList* types = expr->GetReceiverTypes();
3504 LookupResult lookup; 3504 LookupResult lookup;
3505 3505
3506 if (expr->IsMonomorphic()) { 3506 if (expr->IsMonomorphic()) {
3507 instr = BuildStoreNamed(object, value, expr); 3507 instr = BuildStoreNamed(object, value, expr);
3508 3508
3509 } else if (types != NULL && types->length() > 1) { 3509 } else if (types != NULL && types->length() > 1) {
3510 HandlePolymorphicStoreNamedField(expr, object, value, types, name); 3510 HandlePolymorphicStoreNamedField(expr, object, value, types, name);
3511 return; 3511 return;
3512 3512
3513 } else { 3513 } else {
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
3979 HValue* key, 3979 HValue* key,
3980 HValue* val, 3980 HValue* val,
3981 Expression* prop, 3981 Expression* prop,
3982 int ast_id, 3982 int ast_id,
3983 int position, 3983 int position,
3984 bool is_store, 3984 bool is_store,
3985 bool* has_side_effects) { 3985 bool* has_side_effects) {
3986 *has_side_effects = false; 3986 *has_side_effects = false;
3987 AddInstruction(new(zone()) HCheckNonSmi(object)); 3987 AddInstruction(new(zone()) HCheckNonSmi(object));
3988 AddInstruction(HCheckInstanceType::NewIsSpecObject(object)); 3988 AddInstruction(HCheckInstanceType::NewIsSpecObject(object));
3989 ZoneMapList* maps = prop->GetReceiverTypes(); 3989 SmallMapList* maps = prop->GetReceiverTypes();
3990 bool todo_external_array = false; 3990 bool todo_external_array = false;
3991 3991
3992 static const int kNumElementTypes = JSObject::kElementsKindCount; 3992 static const int kNumElementTypes = JSObject::kElementsKindCount;
3993 bool type_todo[kNumElementTypes]; 3993 bool type_todo[kNumElementTypes];
3994 for (int i = 0; i < kNumElementTypes; ++i) { 3994 for (int i = 0; i < kNumElementTypes; ++i) {
3995 type_todo[i] = false; 3995 type_todo[i] = false;
3996 } 3996 }
3997 3997
3998 for (int i = 0; i < maps->length(); ++i) { 3998 for (int i = 0; i < maps->length(); ++i) {
3999 ASSERT(maps->at(i)->IsMap()); 3999 ASSERT(maps->at(i)->IsMap());
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
4253 AddInstruction(char_code); 4253 AddInstruction(char_code);
4254 instr = new(zone()) HStringCharFromCode(context, char_code); 4254 instr = new(zone()) HStringCharFromCode(context, char_code);
4255 4255
4256 } else if (expr->IsFunctionPrototype()) { 4256 } else if (expr->IsFunctionPrototype()) {
4257 HValue* function = Pop(); 4257 HValue* function = Pop();
4258 AddInstruction(new(zone()) HCheckNonSmi(function)); 4258 AddInstruction(new(zone()) HCheckNonSmi(function));
4259 instr = new(zone()) HLoadFunctionPrototype(function); 4259 instr = new(zone()) HLoadFunctionPrototype(function);
4260 4260
4261 } else if (expr->key()->IsPropertyName()) { 4261 } else if (expr->key()->IsPropertyName()) {
4262 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 4262 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
4263 ZoneMapList* types = expr->GetReceiverTypes(); 4263 SmallMapList* types = expr->GetReceiverTypes();
4264 4264
4265 HValue* obj = Pop(); 4265 HValue* obj = Pop();
4266 if (expr->IsMonomorphic()) { 4266 if (expr->IsMonomorphic()) {
4267 instr = BuildLoadNamed(obj, expr, types->first(), name); 4267 instr = BuildLoadNamed(obj, expr, types->first(), name);
4268 } else if (types != NULL && types->length() > 1) { 4268 } else if (types != NULL && types->length() > 1) {
4269 AddInstruction(new(zone()) HCheckNonSmi(obj)); 4269 AddInstruction(new(zone()) HCheckNonSmi(obj));
4270 HValue* context = environment()->LookupContext(); 4270 HValue* context = environment()->LookupContext();
4271 instr = new(zone()) HLoadNamedFieldPolymorphic(context, obj, types, name); 4271 instr = new(zone()) HLoadNamedFieldPolymorphic(context, obj, types, name);
4272 } else { 4272 } else {
4273 instr = BuildLoadNamedGeneric(obj, expr); 4273 instr = BuildLoadNamedGeneric(obj, expr);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
4314 if (!expr->holder().is_null()) { 4314 if (!expr->holder().is_null()) {
4315 AddInstruction(new(zone()) HCheckPrototypeMaps( 4315 AddInstruction(new(zone()) HCheckPrototypeMaps(
4316 Handle<JSObject>(JSObject::cast(receiver_map->prototype())), 4316 Handle<JSObject>(JSObject::cast(receiver_map->prototype())),
4317 expr->holder())); 4317 expr->holder()));
4318 } 4318 }
4319 } 4319 }
4320 4320
4321 4321
4322 void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr, 4322 void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr,
4323 HValue* receiver, 4323 HValue* receiver,
4324 ZoneMapList* types, 4324 SmallMapList* types,
4325 Handle<String> name) { 4325 Handle<String> name) {
4326 // TODO(ager): We should recognize when the prototype chains for different 4326 // TODO(ager): We should recognize when the prototype chains for different
4327 // maps are identical. In that case we can avoid repeatedly generating the 4327 // maps are identical. In that case we can avoid repeatedly generating the
4328 // same prototype map checks. 4328 // same prototype map checks.
4329 int argument_count = expr->arguments()->length() + 1; // Includes receiver. 4329 int argument_count = expr->arguments()->length() + 1; // Includes receiver.
4330 int count = 0; 4330 int count = 0;
4331 HBasicBlock* join = NULL; 4331 HBasicBlock* join = NULL;
4332 for (int i = 0; i < types->length() && count < kMaxCallPolymorphism; ++i) { 4332 for (int i = 0; i < types->length() && count < kMaxCallPolymorphism; ++i) {
4333 Handle<Map> map = types->at(i); 4333 Handle<Map> map = types->at(i);
4334 if (expr->ComputeTarget(map, name)) { 4334 if (expr->ComputeTarget(map, name)) {
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
4842 // Named function call. 4842 // Named function call.
4843 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD); 4843 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD);
4844 4844
4845 if (TryCallApply(expr)) return; 4845 if (TryCallApply(expr)) return;
4846 4846
4847 CHECK_ALIVE(VisitForValue(prop->obj())); 4847 CHECK_ALIVE(VisitForValue(prop->obj()));
4848 CHECK_ALIVE(VisitExpressions(expr->arguments())); 4848 CHECK_ALIVE(VisitExpressions(expr->arguments()));
4849 4849
4850 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 4850 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
4851 4851
4852 ZoneMapList* types = expr->GetReceiverTypes(); 4852 SmallMapList* types = expr->GetReceiverTypes();
4853 4853
4854 HValue* receiver = 4854 HValue* receiver =
4855 environment()->ExpressionStackAt(expr->arguments()->length()); 4855 environment()->ExpressionStackAt(expr->arguments()->length());
4856 if (expr->IsMonomorphic()) { 4856 if (expr->IsMonomorphic()) {
4857 Handle<Map> receiver_map = 4857 Handle<Map> receiver_map = (types == NULL || types->is_empty())
4858 (types == NULL) ? Handle<Map>::null() : types->first(); 4858 ? Handle<Map>::null()
4859 : types->first();
4859 if (TryInlineBuiltinFunction(expr, 4860 if (TryInlineBuiltinFunction(expr,
4860 receiver, 4861 receiver,
4861 receiver_map, 4862 receiver_map,
4862 expr->check_type())) { 4863 expr->check_type())) {
4863 return; 4864 return;
4864 } 4865 }
4865 4866
4866 if (CallStubCompiler::HasCustomCallGenerator(*expr->target()) || 4867 if (CallStubCompiler::HasCustomCallGenerator(*expr->target()) ||
4867 expr->check_type() != RECEIVER_MAP_CHECK) { 4868 expr->check_type() != RECEIVER_MAP_CHECK) {
4868 // When the target has a custom call IC generator, use the IC, 4869 // When the target has a custom call IC generator, use the IC,
(...skipping 1880 matching lines...) Expand 10 before | Expand all | Expand 10 after
6749 } 6750 }
6750 } 6751 }
6751 6752
6752 #ifdef DEBUG 6753 #ifdef DEBUG
6753 if (graph_ != NULL) graph_->Verify(); 6754 if (graph_ != NULL) graph_->Verify();
6754 if (allocator_ != NULL) allocator_->Verify(); 6755 if (allocator_ != NULL) allocator_->Verify();
6755 #endif 6756 #endif
6756 } 6757 }
6757 6758
6758 } } // namespace v8::internal 6759 } } // namespace v8::internal
OLDNEW
« src/ast.h ('K') | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698