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

Side by Side Diff: src/hydrogen.cc

Issue 7778013: NewGC: Merge bleeding edge up to 9009. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 3 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') | 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 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 2307 matching lines...) Expand 10 before | Expand all | Expand 10 after
2318 } 2318 }
2319 if (FLAG_eliminate_dead_phis) graph()->EliminateUnreachablePhis(); 2319 if (FLAG_eliminate_dead_phis) graph()->EliminateUnreachablePhis();
2320 if (!graph()->CollectPhis()) { 2320 if (!graph()->CollectPhis()) {
2321 Bailout("Unsupported phi use of uninitialized constant"); 2321 Bailout("Unsupported phi use of uninitialized constant");
2322 return NULL; 2322 return NULL;
2323 } 2323 }
2324 2324
2325 HInferRepresentation rep(graph()); 2325 HInferRepresentation rep(graph());
2326 rep.Analyze(); 2326 rep.Analyze();
2327 2327
2328 if (FLAG_use_range) { 2328 graph()->MarkDeoptimizeOnUndefined();
2329 HRangeAnalysis rangeAnalysis(graph()); 2329 graph()->InsertRepresentationChanges();
2330 rangeAnalysis.Analyze();
2331 }
2332 2330
2333 graph()->InitializeInferredTypes(); 2331 graph()->InitializeInferredTypes();
2334 graph()->Canonicalize(); 2332 graph()->Canonicalize();
2335 graph()->MarkDeoptimizeOnUndefined();
2336 graph()->InsertRepresentationChanges();
2337 graph()->ComputeMinusZeroChecks();
2338
2339 // Eliminate redundant stack checks on backwards branches.
2340 HStackCheckEliminator sce(graph());
2341 sce.Process();
2342 2333
2343 // Perform common subexpression elimination and loop-invariant code motion. 2334 // Perform common subexpression elimination and loop-invariant code motion.
2344 if (FLAG_use_gvn) { 2335 if (FLAG_use_gvn) {
2345 HPhase phase("Global value numbering", graph()); 2336 HPhase phase("Global value numbering", graph());
2346 HGlobalValueNumberer gvn(graph(), info()); 2337 HGlobalValueNumberer gvn(graph(), info());
2347 gvn.Analyze(); 2338 gvn.Analyze();
2348 } 2339 }
2349 2340
2341 if (FLAG_use_range) {
2342 HRangeAnalysis rangeAnalysis(graph());
2343 rangeAnalysis.Analyze();
2344 }
2345 graph()->ComputeMinusZeroChecks();
2346
2347 // Eliminate redundant stack checks on backwards branches.
2348 HStackCheckEliminator sce(graph());
2349 sce.Process();
2350
2350 // Replace the results of check instructions with the original value, if the 2351 // Replace the results of check instructions with the original value, if the
2351 // result is used. This is safe now, since we don't do code motion after this 2352 // result is used. This is safe now, since we don't do code motion after this
2352 // point. It enables better register allocation since the value produced by 2353 // point. It enables better register allocation since the value produced by
2353 // check instructions is really a copy of the original value. 2354 // check instructions is really a copy of the original value.
2354 graph()->ReplaceCheckedValues(); 2355 graph()->ReplaceCheckedValues();
2355 2356
2356 return graph(); 2357 return graph();
2357 } 2358 }
2358 2359
2359 2360
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
2473 header->SetInitialEnvironment(entry_env); 2474 header->SetInitialEnvironment(entry_env);
2474 header->AttachLoopInformation(); 2475 header->AttachLoopInformation();
2475 return header; 2476 return header;
2476 } 2477 }
2477 2478
2478 2479
2479 void HGraphBuilder::VisitBlock(Block* stmt) { 2480 void HGraphBuilder::VisitBlock(Block* stmt) {
2480 ASSERT(!HasStackOverflow()); 2481 ASSERT(!HasStackOverflow());
2481 ASSERT(current_block() != NULL); 2482 ASSERT(current_block() != NULL);
2482 ASSERT(current_block()->HasPredecessor()); 2483 ASSERT(current_block()->HasPredecessor());
2484 if (stmt->block_scope() != NULL) {
2485 return Bailout("ScopedBlock");
2486 }
2483 BreakAndContinueInfo break_info(stmt); 2487 BreakAndContinueInfo break_info(stmt);
2484 { BreakAndContinueScope push(&break_info, this); 2488 { BreakAndContinueScope push(&break_info, this);
2485 CHECK_BAILOUT(VisitStatements(stmt->statements())); 2489 CHECK_BAILOUT(VisitStatements(stmt->statements()));
2486 } 2490 }
2487 HBasicBlock* break_block = break_info.break_block(); 2491 HBasicBlock* break_block = break_info.break_block();
2488 if (break_block != NULL) { 2492 if (break_block != NULL) {
2489 if (current_block() != NULL) current_block()->Goto(break_block); 2493 if (current_block() != NULL) current_block()->Goto(break_block);
2490 break_block->SetJoinId(stmt->ExitId()); 2494 break_block->SetJoinId(stmt->ExitId());
2491 set_current_block(break_block); 2495 set_current_block(break_block);
2492 } 2496 }
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
2624 ASSERT(context->IsValue()); 2628 ASSERT(context->IsValue());
2625 CHECK_ALIVE(VisitForValue(stmt->expression())); 2629 CHECK_ALIVE(VisitForValue(stmt->expression()));
2626 HValue* return_value = environment()->Pop(); 2630 HValue* return_value = environment()->Pop();
2627 current_block()->AddLeaveInlined(return_value, function_return()); 2631 current_block()->AddLeaveInlined(return_value, function_return());
2628 } 2632 }
2629 set_current_block(NULL); 2633 set_current_block(NULL);
2630 } 2634 }
2631 } 2635 }
2632 2636
2633 2637
2634 void HGraphBuilder::VisitEnterWithContextStatement( 2638 void HGraphBuilder::VisitWithStatement(WithStatement* stmt) {
2635 EnterWithContextStatement* stmt) {
2636 ASSERT(!HasStackOverflow()); 2639 ASSERT(!HasStackOverflow());
2637 ASSERT(current_block() != NULL); 2640 ASSERT(current_block() != NULL);
2638 ASSERT(current_block()->HasPredecessor()); 2641 ASSERT(current_block()->HasPredecessor());
2639 return Bailout("EnterWithContextStatement"); 2642 return Bailout("WithStatement");
2640 } 2643 }
2641 2644
2642 2645
2643 void HGraphBuilder::VisitExitContextStatement(ExitContextStatement* stmt) { 2646 void HGraphBuilder::VisitExitContextStatement(ExitContextStatement* stmt) {
2644 ASSERT(!HasStackOverflow()); 2647 ASSERT(!HasStackOverflow());
2645 ASSERT(current_block() != NULL); 2648 ASSERT(current_block() != NULL);
2646 ASSERT(current_block()->HasPredecessor()); 2649 ASSERT(current_block()->HasPredecessor());
2647 return Bailout("ExitContextStatement"); 2650 return Bailout("ExitContextStatement");
2648 } 2651 }
2649 2652
(...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after
3386 HValue* value, 3389 HValue* value,
3387 Expression* expr) { 3390 Expression* expr) {
3388 Property* prop = (expr->AsProperty() != NULL) 3391 Property* prop = (expr->AsProperty() != NULL)
3389 ? expr->AsProperty() 3392 ? expr->AsProperty()
3390 : expr->AsAssignment()->target()->AsProperty(); 3393 : expr->AsAssignment()->target()->AsProperty();
3391 Literal* key = prop->key()->AsLiteral(); 3394 Literal* key = prop->key()->AsLiteral();
3392 Handle<String> name = Handle<String>::cast(key->handle()); 3395 Handle<String> name = Handle<String>::cast(key->handle());
3393 ASSERT(!name.is_null()); 3396 ASSERT(!name.is_null());
3394 3397
3395 LookupResult lookup; 3398 LookupResult lookup;
3396 ZoneMapList* types = expr->GetReceiverTypes(); 3399 SmallMapList* types = expr->GetReceiverTypes();
3397 bool is_monomorphic = expr->IsMonomorphic() && 3400 bool is_monomorphic = expr->IsMonomorphic() &&
3398 ComputeStoredField(types->first(), name, &lookup); 3401 ComputeStoredField(types->first(), name, &lookup);
3399 3402
3400 return is_monomorphic 3403 return is_monomorphic
3401 ? BuildStoreNamedField(object, name, value, types->first(), &lookup, 3404 ? BuildStoreNamedField(object, name, value, types->first(), &lookup,
3402 true) // Needs smi and map check. 3405 true) // Needs smi and map check.
3403 : BuildStoreNamedGeneric(object, name, value); 3406 : BuildStoreNamedGeneric(object, name, value);
3404 } 3407 }
3405 3408
3406 3409
3407 void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, 3410 void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr,
3408 HValue* object, 3411 HValue* object,
3409 HValue* value, 3412 HValue* value,
3410 ZoneMapList* types, 3413 SmallMapList* types,
3411 Handle<String> name) { 3414 Handle<String> name) {
3412 // TODO(ager): We should recognize when the prototype chains for different 3415 // TODO(ager): We should recognize when the prototype chains for different
3413 // maps are identical. In that case we can avoid repeatedly generating the 3416 // maps are identical. In that case we can avoid repeatedly generating the
3414 // same prototype map checks. 3417 // same prototype map checks.
3415 int count = 0; 3418 int count = 0;
3416 HBasicBlock* join = NULL; 3419 HBasicBlock* join = NULL;
3417 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { 3420 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) {
3418 Handle<Map> map = types->at(i); 3421 Handle<Map> map = types->at(i);
3419 LookupResult lookup; 3422 LookupResult lookup;
3420 if (ComputeStoredField(map, name, &lookup)) { 3423 if (ComputeStoredField(map, name, &lookup)) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
3491 if (prop->key()->IsPropertyName()) { 3494 if (prop->key()->IsPropertyName()) {
3492 // Named store. 3495 // Named store.
3493 CHECK_ALIVE(VisitForValue(expr->value())); 3496 CHECK_ALIVE(VisitForValue(expr->value()));
3494 value = Pop(); 3497 value = Pop();
3495 HValue* object = Pop(); 3498 HValue* object = Pop();
3496 3499
3497 Literal* key = prop->key()->AsLiteral(); 3500 Literal* key = prop->key()->AsLiteral();
3498 Handle<String> name = Handle<String>::cast(key->handle()); 3501 Handle<String> name = Handle<String>::cast(key->handle());
3499 ASSERT(!name.is_null()); 3502 ASSERT(!name.is_null());
3500 3503
3501 ZoneMapList* types = expr->GetReceiverTypes(); 3504 SmallMapList* types = expr->GetReceiverTypes();
3502 LookupResult lookup; 3505 LookupResult lookup;
3503 3506
3504 if (expr->IsMonomorphic()) { 3507 if (expr->IsMonomorphic()) {
3505 instr = BuildStoreNamed(object, value, expr); 3508 instr = BuildStoreNamed(object, value, expr);
3506 3509
3507 } else if (types != NULL && types->length() > 1) { 3510 } else if (types != NULL && types->length() > 1) {
3508 HandlePolymorphicStoreNamedField(expr, object, value, types, name); 3511 HandlePolymorphicStoreNamedField(expr, object, value, types, name);
3509 return; 3512 return;
3510 3513
3511 } else { 3514 } else {
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
3933 HInstruction* mapcheck = AddInstruction(new(zone()) HCheckMap(object, map)); 3936 HInstruction* mapcheck = AddInstruction(new(zone()) HCheckMap(object, map));
3934 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); 3937 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object));
3935 bool fast_double_elements = map->has_fast_double_elements(); 3938 bool fast_double_elements = map->has_fast_double_elements();
3936 if (is_store && map->has_fast_elements()) { 3939 if (is_store && map->has_fast_elements()) {
3937 AddInstruction(new(zone()) HCheckMap( 3940 AddInstruction(new(zone()) HCheckMap(
3938 elements, isolate()->factory()->fixed_array_map())); 3941 elements, isolate()->factory()->fixed_array_map()));
3939 } 3942 }
3940 HInstruction* length = NULL; 3943 HInstruction* length = NULL;
3941 HInstruction* checked_key = NULL; 3944 HInstruction* checked_key = NULL;
3942 if (map->has_external_array_elements()) { 3945 if (map->has_external_array_elements()) {
3943 length = AddInstruction(new(zone()) HExternalArrayLength(elements)); 3946 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
3944 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); 3947 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
3945 HLoadExternalArrayPointer* external_elements = 3948 HLoadExternalArrayPointer* external_elements =
3946 new(zone()) HLoadExternalArrayPointer(elements); 3949 new(zone()) HLoadExternalArrayPointer(elements);
3947 AddInstruction(external_elements); 3950 AddInstruction(external_elements);
3948 return BuildExternalArrayElementAccess(external_elements, checked_key, 3951 return BuildExternalArrayElementAccess(external_elements, checked_key,
3949 val, map->elements_kind(), is_store); 3952 val, map->elements_kind(), is_store);
3950 } 3953 }
3951 ASSERT(map->has_fast_elements() || fast_double_elements); 3954 ASSERT(map->has_fast_elements() || fast_double_elements);
3952 if (map->instance_type() == JS_ARRAY_TYPE) { 3955 if (map->instance_type() == JS_ARRAY_TYPE) {
3953 length = AddInstruction(new(zone()) HJSArrayLength(object, mapcheck)); 3956 length = AddInstruction(new(zone()) HJSArrayLength(object, mapcheck));
3954 } else { 3957 } else {
3955 length = AddInstruction(new(zone()) HFixedArrayLength(elements)); 3958 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
3956 } 3959 }
3957 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); 3960 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
3958 if (is_store) { 3961 if (is_store) {
3959 if (fast_double_elements) { 3962 if (fast_double_elements) {
3960 return new(zone()) HStoreKeyedFastDoubleElement(elements, 3963 return new(zone()) HStoreKeyedFastDoubleElement(elements,
3961 checked_key, 3964 checked_key,
3962 val); 3965 val);
3963 } else { 3966 } else {
3964 return new(zone()) HStoreKeyedFastElement(elements, checked_key, val); 3967 return new(zone()) HStoreKeyedFastElement(elements, checked_key, val);
3965 } 3968 }
(...skipping 11 matching lines...) Expand all
3977 HValue* key, 3980 HValue* key,
3978 HValue* val, 3981 HValue* val,
3979 Expression* prop, 3982 Expression* prop,
3980 int ast_id, 3983 int ast_id,
3981 int position, 3984 int position,
3982 bool is_store, 3985 bool is_store,
3983 bool* has_side_effects) { 3986 bool* has_side_effects) {
3984 *has_side_effects = false; 3987 *has_side_effects = false;
3985 AddInstruction(new(zone()) HCheckNonSmi(object)); 3988 AddInstruction(new(zone()) HCheckNonSmi(object));
3986 AddInstruction(HCheckInstanceType::NewIsSpecObject(object)); 3989 AddInstruction(HCheckInstanceType::NewIsSpecObject(object));
3987 ZoneMapList* maps = prop->GetReceiverTypes(); 3990 SmallMapList* maps = prop->GetReceiverTypes();
3988 bool todo_external_array = false; 3991 bool todo_external_array = false;
3989 3992
3990 static const int kNumElementTypes = JSObject::kElementsKindCount; 3993 static const int kNumElementTypes = JSObject::kElementsKindCount;
3991 bool type_todo[kNumElementTypes]; 3994 bool type_todo[kNumElementTypes];
3992 for (int i = 0; i < kNumElementTypes; ++i) { 3995 for (int i = 0; i < kNumElementTypes; ++i) {
3993 type_todo[i] = false; 3996 type_todo[i] = false;
3994 } 3997 }
3995 3998
3996 for (int i = 0; i < maps->length(); ++i) { 3999 for (int i = 0; i < maps->length(); ++i) {
3997 ASSERT(maps->at(i)->IsMap()); 4000 ASSERT(maps->at(i)->IsMap());
(...skipping 19 matching lines...) Expand all
4017 for (JSObject::ElementsKind elements_kind = JSObject::FAST_ELEMENTS; 4020 for (JSObject::ElementsKind elements_kind = JSObject::FAST_ELEMENTS;
4018 elements_kind <= JSObject::LAST_ELEMENTS_KIND; 4021 elements_kind <= JSObject::LAST_ELEMENTS_KIND;
4019 elements_kind = JSObject::ElementsKind(elements_kind + 1)) { 4022 elements_kind = JSObject::ElementsKind(elements_kind + 1)) {
4020 // After having handled FAST_ELEMENTS and DICTIONARY_ELEMENTS, we 4023 // After having handled FAST_ELEMENTS and DICTIONARY_ELEMENTS, we
4021 // need to add some code that's executed for all external array cases. 4024 // need to add some code that's executed for all external array cases.
4022 STATIC_ASSERT(JSObject::LAST_EXTERNAL_ARRAY_ELEMENTS_KIND == 4025 STATIC_ASSERT(JSObject::LAST_EXTERNAL_ARRAY_ELEMENTS_KIND ==
4023 JSObject::LAST_ELEMENTS_KIND); 4026 JSObject::LAST_ELEMENTS_KIND);
4024 if (elements_kind == JSObject::FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND 4027 if (elements_kind == JSObject::FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND
4025 && todo_external_array) { 4028 && todo_external_array) {
4026 HInstruction* length = 4029 HInstruction* length =
4027 AddInstruction(new(zone()) HExternalArrayLength(elements)); 4030 AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
4028 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); 4031 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
4029 external_elements = new(zone()) HLoadExternalArrayPointer(elements); 4032 external_elements = new(zone()) HLoadExternalArrayPointer(elements);
4030 AddInstruction(external_elements); 4033 AddInstruction(external_elements);
4031 } 4034 }
4032 if (type_todo[elements_kind]) { 4035 if (type_todo[elements_kind]) {
4033 HBasicBlock* if_true = graph()->CreateBasicBlock(); 4036 HBasicBlock* if_true = graph()->CreateBasicBlock();
4034 HBasicBlock* if_false = graph()->CreateBasicBlock(); 4037 HBasicBlock* if_false = graph()->CreateBasicBlock();
4035 elements_kind_branch = new(zone()) HCompareConstantEqAndBranch( 4038 elements_kind_branch = new(zone()) HCompareConstantEqAndBranch(
4036 elements_kind_instr, elements_kind, Token::EQ_STRICT); 4039 elements_kind_instr, elements_kind, Token::EQ_STRICT);
4037 elements_kind_branch->SetSuccessorAt(0, if_true); 4040 elements_kind_branch->SetSuccessorAt(0, if_true);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
4081 } 4084 }
4082 Push(access); 4085 Push(access);
4083 } 4086 }
4084 *has_side_effects |= access->HasSideEffects(); 4087 *has_side_effects |= access->HasSideEffects();
4085 if (position != -1) { 4088 if (position != -1) {
4086 access->set_position(position); 4089 access->set_position(position);
4087 } 4090 }
4088 if_jsarray->Goto(join); 4091 if_jsarray->Goto(join);
4089 4092
4090 set_current_block(if_fastobject); 4093 set_current_block(if_fastobject);
4091 length = AddInstruction(new(zone()) HFixedArrayLength(elements)); 4094 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
4092 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); 4095 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
4093 if (is_store) { 4096 if (is_store) {
4094 if (fast_double_elements) { 4097 if (fast_double_elements) {
4095 access = AddInstruction( 4098 access = AddInstruction(
4096 new(zone()) HStoreKeyedFastDoubleElement(elements, 4099 new(zone()) HStoreKeyedFastDoubleElement(elements,
4097 checked_key, 4100 checked_key,
4098 val)); 4101 val));
4099 } else { 4102 } else {
4100 access = AddInstruction( 4103 access = AddInstruction(
4101 new(zone()) HStoreKeyedFastElement(elements, checked_key, val)); 4104 new(zone()) HStoreKeyedFastElement(elements, checked_key, val));
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
4251 AddInstruction(char_code); 4254 AddInstruction(char_code);
4252 instr = new(zone()) HStringCharFromCode(context, char_code); 4255 instr = new(zone()) HStringCharFromCode(context, char_code);
4253 4256
4254 } else if (expr->IsFunctionPrototype()) { 4257 } else if (expr->IsFunctionPrototype()) {
4255 HValue* function = Pop(); 4258 HValue* function = Pop();
4256 AddInstruction(new(zone()) HCheckNonSmi(function)); 4259 AddInstruction(new(zone()) HCheckNonSmi(function));
4257 instr = new(zone()) HLoadFunctionPrototype(function); 4260 instr = new(zone()) HLoadFunctionPrototype(function);
4258 4261
4259 } else if (expr->key()->IsPropertyName()) { 4262 } else if (expr->key()->IsPropertyName()) {
4260 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 4263 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
4261 ZoneMapList* types = expr->GetReceiverTypes(); 4264 SmallMapList* types = expr->GetReceiverTypes();
4262 4265
4263 HValue* obj = Pop(); 4266 HValue* obj = Pop();
4264 if (expr->IsMonomorphic()) { 4267 if (expr->IsMonomorphic()) {
4265 instr = BuildLoadNamed(obj, expr, types->first(), name); 4268 instr = BuildLoadNamed(obj, expr, types->first(), name);
4266 } else if (types != NULL && types->length() > 1) { 4269 } else if (types != NULL && types->length() > 1) {
4267 AddInstruction(new(zone()) HCheckNonSmi(obj)); 4270 AddInstruction(new(zone()) HCheckNonSmi(obj));
4268 HValue* context = environment()->LookupContext(); 4271 HValue* context = environment()->LookupContext();
4269 instr = new(zone()) HLoadNamedFieldPolymorphic(context, obj, types, name); 4272 instr = new(zone()) HLoadNamedFieldPolymorphic(context, obj, types, name);
4270 } else { 4273 } else {
4271 instr = BuildLoadNamedGeneric(obj, expr); 4274 instr = BuildLoadNamedGeneric(obj, expr);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
4312 if (!expr->holder().is_null()) { 4315 if (!expr->holder().is_null()) {
4313 AddInstruction(new(zone()) HCheckPrototypeMaps( 4316 AddInstruction(new(zone()) HCheckPrototypeMaps(
4314 Handle<JSObject>(JSObject::cast(receiver_map->prototype())), 4317 Handle<JSObject>(JSObject::cast(receiver_map->prototype())),
4315 expr->holder())); 4318 expr->holder()));
4316 } 4319 }
4317 } 4320 }
4318 4321
4319 4322
4320 void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr, 4323 void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr,
4321 HValue* receiver, 4324 HValue* receiver,
4322 ZoneMapList* types, 4325 SmallMapList* types,
4323 Handle<String> name) { 4326 Handle<String> name) {
4324 // TODO(ager): We should recognize when the prototype chains for different 4327 // TODO(ager): We should recognize when the prototype chains for different
4325 // maps are identical. In that case we can avoid repeatedly generating the 4328 // maps are identical. In that case we can avoid repeatedly generating the
4326 // same prototype map checks. 4329 // same prototype map checks.
4327 int argument_count = expr->arguments()->length() + 1; // Includes receiver. 4330 int argument_count = expr->arguments()->length() + 1; // Includes receiver.
4328 int count = 0; 4331 int count = 0;
4329 HBasicBlock* join = NULL; 4332 HBasicBlock* join = NULL;
4330 for (int i = 0; i < types->length() && count < kMaxCallPolymorphism; ++i) { 4333 for (int i = 0; i < types->length() && count < kMaxCallPolymorphism; ++i) {
4331 Handle<Map> map = types->at(i); 4334 Handle<Map> map = types->at(i);
4332 if (expr->ComputeTarget(map, name)) { 4335 if (expr->ComputeTarget(map, name)) {
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
4755 } 4758 }
4756 return false; 4759 return false;
4757 } 4760 }
4758 4761
4759 4762
4760 bool HGraphBuilder::TryCallApply(Call* expr) { 4763 bool HGraphBuilder::TryCallApply(Call* expr) {
4761 Expression* callee = expr->expression(); 4764 Expression* callee = expr->expression();
4762 Property* prop = callee->AsProperty(); 4765 Property* prop = callee->AsProperty();
4763 ASSERT(prop != NULL); 4766 ASSERT(prop != NULL);
4764 4767
4768 if (!expr->IsMonomorphic() || expr->check_type() != RECEIVER_MAP_CHECK) {
4769 return false;
4770 }
4771 Handle<Map> function_map = expr->GetReceiverTypes()->first();
4772 if (function_map->instance_type() != JS_FUNCTION_TYPE ||
4773 !expr->target()->shared()->HasBuiltinFunctionId() ||
4774 expr->target()->shared()->builtin_function_id() != kFunctionApply) {
4775 return false;
4776 }
4777
4765 if (info()->scope()->arguments() == NULL) return false; 4778 if (info()->scope()->arguments() == NULL) return false;
4766 4779
4767 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
4768 if (!name->IsEqualTo(CStrVector("apply"))) return false;
4769
4770 ZoneList<Expression*>* args = expr->arguments(); 4780 ZoneList<Expression*>* args = expr->arguments();
4771 if (args->length() != 2) return false; 4781 if (args->length() != 2) return false;
4772 4782
4773 VariableProxy* arg_two = args->at(1)->AsVariableProxy(); 4783 VariableProxy* arg_two = args->at(1)->AsVariableProxy();
4774 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false; 4784 if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false;
4775 HValue* arg_two_value = environment()->Lookup(arg_two->var()); 4785 HValue* arg_two_value = environment()->Lookup(arg_two->var());
4776 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false; 4786 if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false;
4777 4787
4778 if (!expr->IsMonomorphic() ||
4779 expr->check_type() != RECEIVER_MAP_CHECK) return false;
4780
4781 // Our implementation of arguments (based on this stack frame or an 4788 // Our implementation of arguments (based on this stack frame or an
4782 // adapter below it) does not work for inlined functions. 4789 // adapter below it) does not work for inlined functions.
4783 if (function_state()->outer() != NULL) { 4790 if (function_state()->outer() != NULL) {
4784 Bailout("Function.prototype.apply optimization in inlined function"); 4791 Bailout("Function.prototype.apply optimization in inlined function");
4785 return true; 4792 return true;
4786 } 4793 }
4787 4794
4788 // Found pattern f.apply(receiver, arguments). 4795 // Found pattern f.apply(receiver, arguments).
4789 VisitForValue(prop->obj()); 4796 VisitForValue(prop->obj());
4790 if (HasStackOverflow() || current_block() == NULL) return true; 4797 if (HasStackOverflow() || current_block() == NULL) return true;
4791 HValue* function = Pop(); 4798 HValue* function = Pop();
4792 VisitForValue(args->at(0)); 4799 VisitForValue(args->at(0));
4793 if (HasStackOverflow() || current_block() == NULL) return true; 4800 if (HasStackOverflow() || current_block() == NULL) return true;
4794 HValue* receiver = Pop(); 4801 HValue* receiver = Pop();
4795 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements); 4802 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
4796 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements)); 4803 HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements));
4797 AddCheckConstantFunction(expr, 4804 AddCheckConstantFunction(expr, function, function_map, true);
4798 function,
4799 expr->GetReceiverTypes()->first(),
4800 true);
4801 HInstruction* result = 4805 HInstruction* result =
4802 new(zone()) HApplyArguments(function, receiver, length, elements); 4806 new(zone()) HApplyArguments(function, receiver, length, elements);
4803 result->set_position(expr->position()); 4807 result->set_position(expr->position());
4804 ast_context()->ReturnInstruction(result, expr->id()); 4808 ast_context()->ReturnInstruction(result, expr->id());
4805 return true; 4809 return true;
4806 } 4810 }
4807 4811
4808 4812
4809 void HGraphBuilder::VisitCall(Call* expr) { 4813 void HGraphBuilder::VisitCall(Call* expr) {
4810 ASSERT(!HasStackOverflow()); 4814 ASSERT(!HasStackOverflow());
(...skipping 28 matching lines...) Expand all
4839 // Named function call. 4843 // Named function call.
4840 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD); 4844 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD);
4841 4845
4842 if (TryCallApply(expr)) return; 4846 if (TryCallApply(expr)) return;
4843 4847
4844 CHECK_ALIVE(VisitForValue(prop->obj())); 4848 CHECK_ALIVE(VisitForValue(prop->obj()));
4845 CHECK_ALIVE(VisitExpressions(expr->arguments())); 4849 CHECK_ALIVE(VisitExpressions(expr->arguments()));
4846 4850
4847 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); 4851 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
4848 4852
4849 ZoneMapList* types = expr->GetReceiverTypes(); 4853 SmallMapList* types = expr->GetReceiverTypes();
4850 4854
4851 HValue* receiver = 4855 HValue* receiver =
4852 environment()->ExpressionStackAt(expr->arguments()->length()); 4856 environment()->ExpressionStackAt(expr->arguments()->length());
4853 if (expr->IsMonomorphic()) { 4857 if (expr->IsMonomorphic()) {
4854 Handle<Map> receiver_map = 4858 Handle<Map> receiver_map = (types == NULL || types->is_empty())
4855 (types == NULL) ? Handle<Map>::null() : types->first(); 4859 ? Handle<Map>::null()
4860 : types->first();
4856 if (TryInlineBuiltinFunction(expr, 4861 if (TryInlineBuiltinFunction(expr,
4857 receiver, 4862 receiver,
4858 receiver_map, 4863 receiver_map,
4859 expr->check_type())) { 4864 expr->check_type())) {
4860 return; 4865 return;
4861 } 4866 }
4862 4867
4863 if (CallStubCompiler::HasCustomCallGenerator(*expr->target()) || 4868 if (CallStubCompiler::HasCustomCallGenerator(*expr->target()) ||
4864 expr->check_type() != RECEIVER_MAP_CHECK) { 4869 expr->check_type() != RECEIVER_MAP_CHECK) {
4865 // When the target has a custom call IC generator, use the IC, 4870 // When the target has a custom call IC generator, use the IC,
(...skipping 1880 matching lines...) Expand 10 before | Expand all | Expand 10 after
6746 } 6751 }
6747 } 6752 }
6748 6753
6749 #ifdef DEBUG 6754 #ifdef DEBUG
6750 if (graph_ != NULL) graph_->Verify(); 6755 if (graph_ != NULL) graph_->Verify();
6751 if (allocator_ != NULL) allocator_->Verify(); 6756 if (allocator_ != NULL) allocator_->Verify();
6752 #endif 6757 #endif
6753 } 6758 }
6754 6759
6755 } } // namespace v8::internal 6760 } } // 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