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

Side by Side Diff: src/hydrogen-instructions.h

Issue 157503002: A64: Synchronize with r18444. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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-gvn.cc ('k') | src/hydrogen-instructions.cc » ('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 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 1227 matching lines...) Expand 10 before | Expand all | Expand 10 after
1238 } 1238 }
1239 1239
1240 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); } 1240 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
1241 1241
1242 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0; 1242 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
1243 1243
1244 #ifdef DEBUG 1244 #ifdef DEBUG
1245 virtual void Verify() V8_OVERRIDE; 1245 virtual void Verify() V8_OVERRIDE;
1246 #endif 1246 #endif
1247 1247
1248 virtual bool IsCall() { return false; } 1248 virtual bool HasStackCheck() { return false; }
1249 1249
1250 DECLARE_ABSTRACT_INSTRUCTION(Instruction) 1250 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
1251 1251
1252 protected: 1252 protected:
1253 HInstruction(HType type = HType::Tagged()) 1253 HInstruction(HType type = HType::Tagged())
1254 : HValue(type), 1254 : HValue(type),
1255 next_(NULL), 1255 next_(NULL),
1256 previous_(NULL), 1256 previous_(NULL),
1257 position_(RelocInfo::kNoPosition) { 1257 position_(RelocInfo::kNoPosition) {
1258 SetGVNFlag(kDependsOnOsrEntries); 1258 SetGVNFlag(kDependsOnOsrEntries);
(...skipping 977 matching lines...) Expand 10 before | Expand all | Expand 10 after
2236 } 2236 }
2237 2237
2238 virtual int argument_count() const { 2238 virtual int argument_count() const {
2239 return argument_count_; 2239 return argument_count_;
2240 } 2240 }
2241 2241
2242 virtual int argument_delta() const V8_OVERRIDE { 2242 virtual int argument_delta() const V8_OVERRIDE {
2243 return -argument_count(); 2243 return -argument_count();
2244 } 2244 }
2245 2245
2246 virtual bool IsCall() V8_FINAL V8_OVERRIDE { return true; }
2247
2248 private: 2246 private:
2249 int argument_count_; 2247 int argument_count_;
2250 }; 2248 };
2251 2249
2252 2250
2253 class HUnaryCall : public HCall<1> { 2251 class HUnaryCall : public HCall<1> {
2254 public: 2252 public:
2255 HUnaryCall(HValue* value, int argument_count) 2253 HUnaryCall(HValue* value, int argument_count)
2256 : HCall<1>(argument_count) { 2254 : HCall<1>(argument_count) {
2257 SetOperandAt(0, value); 2255 SetOperandAt(0, value);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2293 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HInvokeFunction, HValue*, int); 2291 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HInvokeFunction, HValue*, int);
2294 2292
2295 HInvokeFunction(HValue* context, 2293 HInvokeFunction(HValue* context,
2296 HValue* function, 2294 HValue* function,
2297 Handle<JSFunction> known_function, 2295 Handle<JSFunction> known_function,
2298 int argument_count) 2296 int argument_count)
2299 : HBinaryCall(context, function, argument_count), 2297 : HBinaryCall(context, function, argument_count),
2300 known_function_(known_function) { 2298 known_function_(known_function) {
2301 formal_parameter_count_ = known_function.is_null() 2299 formal_parameter_count_ = known_function.is_null()
2302 ? 0 : known_function->shared()->formal_parameter_count(); 2300 ? 0 : known_function->shared()->formal_parameter_count();
2301 has_stack_check_ = !known_function.is_null() &&
2302 (known_function->code()->kind() == Code::FUNCTION ||
2303 known_function->code()->kind() == Code::OPTIMIZED_FUNCTION);
2303 } 2304 }
2304 2305
2305 static HInvokeFunction* New(Zone* zone, 2306 static HInvokeFunction* New(Zone* zone,
2306 HValue* context, 2307 HValue* context,
2307 HValue* function, 2308 HValue* function,
2308 Handle<JSFunction> known_function, 2309 Handle<JSFunction> known_function,
2309 int argument_count) { 2310 int argument_count) {
2310 return new(zone) HInvokeFunction(context, function, 2311 return new(zone) HInvokeFunction(context, function,
2311 known_function, argument_count); 2312 known_function, argument_count);
2312 } 2313 }
2313 2314
2314 HValue* context() { return first(); } 2315 HValue* context() { return first(); }
2315 HValue* function() { return second(); } 2316 HValue* function() { return second(); }
2316 Handle<JSFunction> known_function() { return known_function_; } 2317 Handle<JSFunction> known_function() { return known_function_; }
2317 int formal_parameter_count() const { return formal_parameter_count_; } 2318 int formal_parameter_count() const { return formal_parameter_count_; }
2318 2319
2320 virtual bool HasStackCheck() V8_FINAL V8_OVERRIDE {
2321 return has_stack_check_;
2322 }
2323
2319 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction) 2324 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
2320 2325
2321 private: 2326 private:
2322 HInvokeFunction(HValue* context, HValue* function, int argument_count) 2327 HInvokeFunction(HValue* context, HValue* function, int argument_count)
2323 : HBinaryCall(context, function, argument_count) { 2328 : HBinaryCall(context, function, argument_count),
2329 has_stack_check_(false) {
2324 } 2330 }
2325 2331
2326 Handle<JSFunction> known_function_; 2332 Handle<JSFunction> known_function_;
2327 int formal_parameter_count_; 2333 int formal_parameter_count_;
2334 bool has_stack_check_;
2328 }; 2335 };
2329 2336
2330 2337
2331 class HCallConstantFunction V8_FINAL : public HCall<0> { 2338 class HCallConstantFunction V8_FINAL : public HCall<0> {
2332 public: 2339 public:
2333 DECLARE_INSTRUCTION_FACTORY_P2(HCallConstantFunction, 2340 DECLARE_INSTRUCTION_FACTORY_P2(HCallConstantFunction,
2334 Handle<JSFunction>, 2341 Handle<JSFunction>,
2335 int); 2342 int);
2336 2343
2337 Handle<JSFunction> function() const { return function_; } 2344 Handle<JSFunction> function() const { return function_; }
2338 int formal_parameter_count() const { return formal_parameter_count_; } 2345 int formal_parameter_count() const { return formal_parameter_count_; }
2339 2346
2340 bool IsApplyFunction() const { 2347 bool IsApplyFunction() const {
2341 return function_->code() == 2348 return function_->code() ==
2342 function_->GetIsolate()->builtins()->builtin(Builtins::kFunctionApply); 2349 function_->GetIsolate()->builtins()->builtin(Builtins::kFunctionApply);
2343 } 2350 }
2344 2351
2345 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 2352 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2346 2353
2347 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 2354 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
2348 return Representation::None(); 2355 return Representation::None();
2349 } 2356 }
2350 2357
2358 virtual bool HasStackCheck() V8_FINAL V8_OVERRIDE {
2359 return has_stack_check_;
2360 }
2361
2351 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction) 2362 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
2352 2363
2353 private: 2364 private:
2354 HCallConstantFunction(Handle<JSFunction> function, int argument_count) 2365 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
2355 : HCall<0>(argument_count), 2366 : HCall<0>(argument_count),
2356 function_(function), 2367 function_(function),
2357 formal_parameter_count_(function->shared()->formal_parameter_count()) {} 2368 formal_parameter_count_(function->shared()->formal_parameter_count()),
2369 has_stack_check_(
2370 function->code()->kind() == Code::FUNCTION ||
2371 function->code()->kind() == Code::OPTIMIZED_FUNCTION) {}
2358 2372
2359 Handle<JSFunction> function_; 2373 Handle<JSFunction> function_;
2360 int formal_parameter_count_; 2374 int formal_parameter_count_;
2375 bool has_stack_check_;
2361 }; 2376 };
2362 2377
2363 2378
2364 class HCallKeyed V8_FINAL : public HBinaryCall { 2379 class HCallKeyed V8_FINAL : public HBinaryCall {
2365 public: 2380 public:
2366 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallKeyed, HValue*, int); 2381 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallKeyed, HValue*, int);
2367 2382
2368 HValue* context() { return first(); } 2383 HValue* context() { return first(); }
2369 HValue* key() { return second(); } 2384 HValue* key() { return second(); }
2370 2385
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
2458 2473
2459 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 2474 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2460 2475
2461 Handle<JSFunction> target() const { return target_; } 2476 Handle<JSFunction> target() const { return target_; }
2462 int formal_parameter_count() const { return formal_parameter_count_; } 2477 int formal_parameter_count() const { return formal_parameter_count_; }
2463 2478
2464 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 2479 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
2465 return Representation::None(); 2480 return Representation::None();
2466 } 2481 }
2467 2482
2483 virtual bool HasStackCheck() V8_FINAL V8_OVERRIDE {
2484 return has_stack_check_;
2485 }
2486
2468 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal) 2487 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
2469 2488
2470 private: 2489 private:
2471 HCallKnownGlobal(Handle<JSFunction> target, int argument_count) 2490 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
2472 : HCall<0>(argument_count), 2491 : HCall<0>(argument_count),
2473 target_(target), 2492 target_(target),
2474 formal_parameter_count_(target->shared()->formal_parameter_count()) { } 2493 formal_parameter_count_(target->shared()->formal_parameter_count()),
2494 has_stack_check_(
2495 target->code()->kind() == Code::FUNCTION ||
2496 target->code()->kind() == Code::OPTIMIZED_FUNCTION) {}
2475 2497
2476 Handle<JSFunction> target_; 2498 Handle<JSFunction> target_;
2477 int formal_parameter_count_; 2499 int formal_parameter_count_;
2500 bool has_stack_check_;
2478 }; 2501 };
2479 2502
2480 2503
2481 class HCallNew V8_FINAL : public HBinaryCall { 2504 class HCallNew V8_FINAL : public HBinaryCall {
2482 public: 2505 public:
2483 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallNew, HValue*, int); 2506 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallNew, HValue*, int);
2484 2507
2485 HValue* context() { return first(); } 2508 HValue* context() { return first(); }
2486 HValue* constructor() { return second(); } 2509 HValue* constructor() { return second(); }
2487 2510
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
2675 set_representation(Representation::Integer32()); 2698 set_representation(Representation::Integer32());
2676 break; 2699 break;
2677 case kMathAbs: 2700 case kMathAbs:
2678 // Not setting representation here: it is None intentionally. 2701 // Not setting representation here: it is None intentionally.
2679 SetFlag(kFlexibleRepresentation); 2702 SetFlag(kFlexibleRepresentation);
2680 // TODO(svenpanne) This flag is actually only needed if representation() 2703 // TODO(svenpanne) This flag is actually only needed if representation()
2681 // is tagged, and not when it is an unboxed double or unboxed integer. 2704 // is tagged, and not when it is an unboxed double or unboxed integer.
2682 SetGVNFlag(kChangesNewSpacePromotion); 2705 SetGVNFlag(kChangesNewSpacePromotion);
2683 break; 2706 break;
2684 case kMathLog: 2707 case kMathLog:
2685 set_representation(Representation::Double());
2686 // These operations use the TranscendentalCache, so they may allocate.
2687 SetGVNFlag(kChangesNewSpacePromotion);
2688 break;
2689 case kMathExp: 2708 case kMathExp:
2690 case kMathSqrt: 2709 case kMathSqrt:
2691 case kMathPowHalf: 2710 case kMathPowHalf:
2692 set_representation(Representation::Double()); 2711 set_representation(Representation::Double());
2693 break; 2712 break;
2694 default: 2713 default:
2695 UNREACHABLE(); 2714 UNREACHABLE();
2696 } 2715 }
2697 SetFlag(kUseGVN); 2716 SetFlag(kUseGVN);
2698 SetFlag(kAllowUndefinedAsNaN); 2717 SetFlag(kAllowUndefinedAsNaN);
(...skipping 2581 matching lines...) Expand 10 before | Expand all | Expand 10 after
5280 }; 5299 };
5281 5300
5282 5301
5283 class HCallStub V8_FINAL : public HUnaryCall { 5302 class HCallStub V8_FINAL : public HUnaryCall {
5284 public: 5303 public:
5285 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallStub, CodeStub::Major, int); 5304 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HCallStub, CodeStub::Major, int);
5286 CodeStub::Major major_key() { return major_key_; } 5305 CodeStub::Major major_key() { return major_key_; }
5287 5306
5288 HValue* context() { return value(); } 5307 HValue* context() { return value(); }
5289 5308
5290 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
5291 transcendental_type_ = transcendental_type;
5292 }
5293 TranscendentalCache::Type transcendental_type() {
5294 return transcendental_type_;
5295 }
5296
5297 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 5309 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
5298 5310
5299 DECLARE_CONCRETE_INSTRUCTION(CallStub) 5311 DECLARE_CONCRETE_INSTRUCTION(CallStub)
5300 5312
5301 private: 5313 private:
5302 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count) 5314 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
5303 : HUnaryCall(context, argument_count), 5315 : HUnaryCall(context, argument_count),
5304 major_key_(major_key), 5316 major_key_(major_key) {
5305 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
5306 } 5317 }
5307 5318
5308 CodeStub::Major major_key_; 5319 CodeStub::Major major_key_;
5309 TranscendentalCache::Type transcendental_type_;
5310 }; 5320 };
5311 5321
5312 5322
5313 class HUnknownOSRValue V8_FINAL : public HTemplateInstruction<0> { 5323 class HUnknownOSRValue V8_FINAL : public HTemplateInstruction<0> {
5314 public: 5324 public:
5315 DECLARE_INSTRUCTION_FACTORY_P2(HUnknownOSRValue, HEnvironment*, int); 5325 DECLARE_INSTRUCTION_FACTORY_P2(HUnknownOSRValue, HEnvironment*, int);
5316 5326
5317 virtual void PrintDataTo(StringStream* stream); 5327 virtual void PrintDataTo(StringStream* stream);
5318 5328
5319 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 5329 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
5421 SetAllSideEffects(); 5431 SetAllSideEffects();
5422 } 5432 }
5423 5433
5424 Handle<Object> name_; 5434 Handle<Object> name_;
5425 bool for_typeof_; 5435 bool for_typeof_;
5426 }; 5436 };
5427 5437
5428 5438
5429 class HAllocate V8_FINAL : public HTemplateInstruction<2> { 5439 class HAllocate V8_FINAL : public HTemplateInstruction<2> {
5430 public: 5440 public:
5441 static bool CompatibleInstanceTypes(InstanceType type1,
5442 InstanceType type2) {
5443 return ComputeFlags(TENURED, type1) == ComputeFlags(TENURED, type2) &&
5444 ComputeFlags(NOT_TENURED, type1) == ComputeFlags(NOT_TENURED, type2);
5445 }
5446
5431 static HAllocate* New(Zone* zone, 5447 static HAllocate* New(Zone* zone,
5432 HValue* context, 5448 HValue* context,
5433 HValue* size, 5449 HValue* size,
5434 HType type, 5450 HType type,
5435 PretenureFlag pretenure_flag, 5451 PretenureFlag pretenure_flag,
5436 InstanceType instance_type, 5452 InstanceType instance_type,
5437 Handle<AllocationSite> allocation_site = 5453 Handle<AllocationSite> allocation_site =
5438 Handle<AllocationSite>::null()) { 5454 Handle<AllocationSite>::null()) {
5439 return new(zone) HAllocate(context, size, type, pretenure_flag, 5455 return new(zone) HAllocate(context, size, type, pretenure_flag,
5440 instance_type, allocation_site); 5456 instance_type, allocation_site);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
5479 } 5495 }
5480 5496
5481 bool MustPrefillWithFiller() const { 5497 bool MustPrefillWithFiller() const {
5482 return (flags_ & PREFILL_WITH_FILLER) != 0; 5498 return (flags_ & PREFILL_WITH_FILLER) != 0;
5483 } 5499 }
5484 5500
5485 void MakePrefillWithFiller() { 5501 void MakePrefillWithFiller() {
5486 flags_ = static_cast<HAllocate::Flags>(flags_ | PREFILL_WITH_FILLER); 5502 flags_ = static_cast<HAllocate::Flags>(flags_ | PREFILL_WITH_FILLER);
5487 } 5503 }
5488 5504
5505 bool MustClearNextMapWord() const {
5506 return (flags_ & CLEAR_NEXT_MAP_WORD) != 0;
5507 }
5508
5489 void MakeDoubleAligned() { 5509 void MakeDoubleAligned() {
5490 flags_ = static_cast<HAllocate::Flags>(flags_ | ALLOCATE_DOUBLE_ALIGNED); 5510 flags_ = static_cast<HAllocate::Flags>(flags_ | ALLOCATE_DOUBLE_ALIGNED);
5491 } 5511 }
5492 5512
5493 virtual void HandleSideEffectDominator(GVNFlag side_effect, 5513 virtual void HandleSideEffectDominator(GVNFlag side_effect,
5494 HValue* dominator) V8_OVERRIDE; 5514 HValue* dominator) V8_OVERRIDE;
5495 5515
5496 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 5516 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
5497 5517
5498 DECLARE_CONCRETE_INSTRUCTION(Allocate) 5518 DECLARE_CONCRETE_INSTRUCTION(Allocate)
5499 5519
5500 private: 5520 private:
5501 enum Flags { 5521 enum Flags {
5502 ALLOCATE_IN_NEW_SPACE = 1 << 0, 5522 ALLOCATE_IN_NEW_SPACE = 1 << 0,
5503 ALLOCATE_IN_OLD_DATA_SPACE = 1 << 1, 5523 ALLOCATE_IN_OLD_DATA_SPACE = 1 << 1,
5504 ALLOCATE_IN_OLD_POINTER_SPACE = 1 << 2, 5524 ALLOCATE_IN_OLD_POINTER_SPACE = 1 << 2,
5505 ALLOCATE_DOUBLE_ALIGNED = 1 << 3, 5525 ALLOCATE_DOUBLE_ALIGNED = 1 << 3,
5506 PREFILL_WITH_FILLER = 1 << 4 5526 PREFILL_WITH_FILLER = 1 << 4,
5527 CLEAR_NEXT_MAP_WORD = 1 << 5
5507 }; 5528 };
5508 5529
5509 HAllocate(HValue* context, 5530 HAllocate(HValue* context,
5510 HValue* size, 5531 HValue* size,
5511 HType type, 5532 HType type,
5512 PretenureFlag pretenure_flag, 5533 PretenureFlag pretenure_flag,
5513 InstanceType instance_type, 5534 InstanceType instance_type,
5514 Handle<AllocationSite> allocation_site = 5535 Handle<AllocationSite> allocation_site =
5515 Handle<AllocationSite>::null()) 5536 Handle<AllocationSite>::null())
5516 : HTemplateInstruction<2>(type), 5537 : HTemplateInstruction<2>(type),
5538 flags_(ComputeFlags(pretenure_flag, instance_type)),
5517 dominating_allocate_(NULL), 5539 dominating_allocate_(NULL),
5518 filler_free_space_size_(NULL), 5540 filler_free_space_size_(NULL) {
5519 clear_next_map_word_(false) {
5520 SetOperandAt(0, context); 5541 SetOperandAt(0, context);
5521 SetOperandAt(1, size); 5542 SetOperandAt(1, size);
5522 set_representation(Representation::Tagged()); 5543 set_representation(Representation::Tagged());
5523 SetFlag(kTrackSideEffectDominators); 5544 SetFlag(kTrackSideEffectDominators);
5524 SetGVNFlag(kChangesNewSpacePromotion); 5545 SetGVNFlag(kChangesNewSpacePromotion);
5525 SetGVNFlag(kDependsOnNewSpacePromotion); 5546 SetGVNFlag(kDependsOnNewSpacePromotion);
5526 flags_ = pretenure_flag == TENURED 5547
5548 if (FLAG_trace_pretenuring) {
5549 PrintF("HAllocate with AllocationSite %p %s\n",
5550 allocation_site.is_null()
5551 ? static_cast<void*>(NULL)
5552 : static_cast<void*>(*allocation_site),
5553 pretenure_flag == TENURED ? "tenured" : "not tenured");
5554 }
5555 }
5556
5557 static Flags ComputeFlags(PretenureFlag pretenure_flag,
5558 InstanceType instance_type) {
5559 Flags flags = pretenure_flag == TENURED
5527 ? (Heap::TargetSpaceId(instance_type) == OLD_POINTER_SPACE 5560 ? (Heap::TargetSpaceId(instance_type) == OLD_POINTER_SPACE
5528 ? ALLOCATE_IN_OLD_POINTER_SPACE : ALLOCATE_IN_OLD_DATA_SPACE) 5561 ? ALLOCATE_IN_OLD_POINTER_SPACE : ALLOCATE_IN_OLD_DATA_SPACE)
5529 : ALLOCATE_IN_NEW_SPACE; 5562 : ALLOCATE_IN_NEW_SPACE;
5530 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) { 5563 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
5531 flags_ = static_cast<HAllocate::Flags>(flags_ | ALLOCATE_DOUBLE_ALIGNED); 5564 flags = static_cast<Flags>(flags | ALLOCATE_DOUBLE_ALIGNED);
5532 } 5565 }
5533 // We have to fill the allocated object with one word fillers if we do 5566 // We have to fill the allocated object with one word fillers if we do
5534 // not use allocation folding since some allocations may depend on each 5567 // not use allocation folding since some allocations may depend on each
5535 // other, i.e., have a pointer to each other. A GC in between these 5568 // other, i.e., have a pointer to each other. A GC in between these
5536 // allocations may leave such objects behind in a not completely initialized 5569 // allocations may leave such objects behind in a not completely initialized
5537 // state. 5570 // state.
5538 if (!FLAG_use_gvn || !FLAG_use_allocation_folding) { 5571 if (!FLAG_use_gvn || !FLAG_use_allocation_folding) {
5539 flags_ = static_cast<HAllocate::Flags>(flags_ | PREFILL_WITH_FILLER); 5572 flags = static_cast<Flags>(flags | PREFILL_WITH_FILLER);
5540 } 5573 }
5541 clear_next_map_word_ = pretenure_flag == NOT_TENURED && 5574 if (pretenure_flag == NOT_TENURED &&
5542 AllocationSite::CanTrack(instance_type); 5575 AllocationSite::CanTrack(instance_type)) {
5576 flags = static_cast<Flags>(flags | CLEAR_NEXT_MAP_WORD);
5577 }
5578 return flags;
5579 }
5543 5580
5544 if (FLAG_trace_pretenuring) { 5581 void UpdateClearNextMapWord(bool clear_next_map_word) {
5545 PrintF("HAllocate with AllocationSite %p %s\n", 5582 flags_ = static_cast<Flags>(clear_next_map_word
5546 allocation_site.is_null() 5583 ? flags_ | CLEAR_NEXT_MAP_WORD
5547 ? static_cast<void*>(NULL) 5584 : flags_ & ~CLEAR_NEXT_MAP_WORD);
5548 : static_cast<void*>(*allocation_site),
5549 pretenure_flag == TENURED ? "tenured" : "not tenured");
5550 }
5551 } 5585 }
5552 5586
5553 void UpdateSize(HValue* size) { 5587 void UpdateSize(HValue* size) {
5554 SetOperandAt(1, size); 5588 SetOperandAt(1, size);
5555 } 5589 }
5556 5590
5557 HAllocate* GetFoldableDominator(HAllocate* dominator); 5591 HAllocate* GetFoldableDominator(HAllocate* dominator);
5558 5592
5559 void UpdateFreeSpaceFiller(int32_t filler_size); 5593 void UpdateFreeSpaceFiller(int32_t filler_size);
5560 5594
5561 void CreateFreeSpaceFiller(int32_t filler_size); 5595 void CreateFreeSpaceFiller(int32_t filler_size);
5562 5596
5563 bool IsFoldable(HAllocate* allocate) { 5597 bool IsFoldable(HAllocate* allocate) {
5564 return (IsNewSpaceAllocation() && allocate->IsNewSpaceAllocation()) || 5598 return (IsNewSpaceAllocation() && allocate->IsNewSpaceAllocation()) ||
5565 (IsOldDataSpaceAllocation() && allocate->IsOldDataSpaceAllocation()) || 5599 (IsOldDataSpaceAllocation() && allocate->IsOldDataSpaceAllocation()) ||
5566 (IsOldPointerSpaceAllocation() && 5600 (IsOldPointerSpaceAllocation() &&
5567 allocate->IsOldPointerSpaceAllocation()); 5601 allocate->IsOldPointerSpaceAllocation());
5568 } 5602 }
5569 5603
5570 void ClearNextMapWord(int offset); 5604 void ClearNextMapWord(int offset);
5571 5605
5572 Flags flags_; 5606 Flags flags_;
5573 Handle<Map> known_initial_map_; 5607 Handle<Map> known_initial_map_;
5574 HAllocate* dominating_allocate_; 5608 HAllocate* dominating_allocate_;
5575 HStoreNamedField* filler_free_space_size_; 5609 HStoreNamedField* filler_free_space_size_;
5576 bool clear_next_map_word_;
5577 }; 5610 };
5578 5611
5579 5612
5580 class HStoreCodeEntry V8_FINAL: public HTemplateInstruction<2> { 5613 class HStoreCodeEntry V8_FINAL: public HTemplateInstruction<2> {
5581 public: 5614 public:
5582 static HStoreCodeEntry* New(Zone* zone, 5615 static HStoreCodeEntry* New(Zone* zone,
5583 HValue* context, 5616 HValue* context,
5584 HValue* function, 5617 HValue* function,
5585 HValue* code) { 5618 HValue* code) {
5586 return new(zone) HStoreCodeEntry(function, code); 5619 return new(zone) HStoreCodeEntry(function, code);
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
6011 } 6044 }
6012 6045
6013 static HObjectAccess ForFirstCodeSlot() { 6046 static HObjectAccess ForFirstCodeSlot() {
6014 return HObjectAccess(kInobject, SharedFunctionInfo::kFirstCodeSlot); 6047 return HObjectAccess(kInobject, SharedFunctionInfo::kFirstCodeSlot);
6015 } 6048 }
6016 6049
6017 static HObjectAccess ForFirstContextSlot() { 6050 static HObjectAccess ForFirstContextSlot() {
6018 return HObjectAccess(kInobject, SharedFunctionInfo::kFirstContextSlot); 6051 return HObjectAccess(kInobject, SharedFunctionInfo::kFirstContextSlot);
6019 } 6052 }
6020 6053
6054 static HObjectAccess ForFirstOsrAstIdSlot() {
6055 return HObjectAccess(kInobject, SharedFunctionInfo::kFirstOsrAstIdSlot);
6056 }
6057
6021 static HObjectAccess ForOptimizedCodeMap() { 6058 static HObjectAccess ForOptimizedCodeMap() {
6022 return HObjectAccess(kInobject, 6059 return HObjectAccess(kInobject,
6023 SharedFunctionInfo::kOptimizedCodeMapOffset); 6060 SharedFunctionInfo::kOptimizedCodeMapOffset);
6024 } 6061 }
6025 6062
6026 static HObjectAccess ForFunctionContextPointer() { 6063 static HObjectAccess ForFunctionContextPointer() {
6027 return HObjectAccess(kInobject, JSFunction::kContextOffset); 6064 return HObjectAccess(kInobject, JSFunction::kContextOffset);
6028 } 6065 }
6029 6066
6030 static HObjectAccess ForMap() { 6067 static HObjectAccess ForMap() {
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
6209 SetOperandAt(0, object); 6246 SetOperandAt(0, object);
6210 6247
6211 Representation representation = access.representation(); 6248 Representation representation = access.representation();
6212 if (representation.IsInteger8() || 6249 if (representation.IsInteger8() ||
6213 representation.IsUInteger8() || 6250 representation.IsUInteger8() ||
6214 representation.IsInteger16() || 6251 representation.IsInteger16() ||
6215 representation.IsUInteger16()) { 6252 representation.IsUInteger16()) {
6216 set_representation(Representation::Integer32()); 6253 set_representation(Representation::Integer32());
6217 } else if (representation.IsSmi()) { 6254 } else if (representation.IsSmi()) {
6218 set_type(HType::Smi()); 6255 set_type(HType::Smi());
6219 set_representation(representation); 6256 if (SmiValuesAre32Bits()) {
6257 set_representation(Representation::Integer32());
6258 } else {
6259 set_representation(representation);
6260 }
6220 } else if (representation.IsDouble() || 6261 } else if (representation.IsDouble() ||
6221 representation.IsExternal() || 6262 representation.IsExternal() ||
6222 representation.IsInteger32()) { 6263 representation.IsInteger32()) {
6223 set_representation(representation); 6264 set_representation(representation);
6224 } else if (FLAG_track_heap_object_fields && 6265 } else if (FLAG_track_heap_object_fields &&
6225 representation.IsHeapObject()) { 6266 representation.IsHeapObject()) {
6226 set_type(HType::NonPrimitive()); 6267 set_type(HType::NonPrimitive());
6227 set_representation(Representation::Tagged()); 6268 set_representation(Representation::Tagged());
6228 } else { 6269 } else {
6229 set_representation(Representation::Tagged()); 6270 set_representation(Representation::Tagged());
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
6409 // I can detect the case between storing double (holey and fast) and 6450 // I can detect the case between storing double (holey and fast) and
6410 // smi/object by looking at elements_kind_. 6451 // smi/object by looking at elements_kind_.
6411 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) || 6452 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) ||
6412 IsFastDoubleElementsKind(elements_kind)); 6453 IsFastDoubleElementsKind(elements_kind));
6413 6454
6414 if (IsFastSmiOrObjectElementsKind(elements_kind)) { 6455 if (IsFastSmiOrObjectElementsKind(elements_kind)) {
6415 if (IsFastSmiElementsKind(elements_kind) && 6456 if (IsFastSmiElementsKind(elements_kind) &&
6416 (!IsHoleyElementsKind(elements_kind) || 6457 (!IsHoleyElementsKind(elements_kind) ||
6417 mode == NEVER_RETURN_HOLE)) { 6458 mode == NEVER_RETURN_HOLE)) {
6418 set_type(HType::Smi()); 6459 set_type(HType::Smi());
6419 set_representation(Representation::Smi()); 6460 if (SmiValuesAre32Bits() && !RequiresHoleCheck()) {
6461 set_representation(Representation::Integer32());
6462 } else {
6463 set_representation(Representation::Smi());
6464 }
6420 } else { 6465 } else {
6421 set_representation(Representation::Tagged()); 6466 set_representation(Representation::Tagged());
6422 } 6467 }
6423 6468
6424 SetGVNFlag(kDependsOnArrayElements); 6469 SetGVNFlag(kDependsOnArrayElements);
6425 } else { 6470 } else {
6426 set_representation(Representation::Double()); 6471 set_representation(Representation::Double());
6427 SetGVNFlag(kDependsOnDoubleArrayElements); 6472 SetGVNFlag(kDependsOnDoubleArrayElements);
6428 } 6473 }
6429 } else { 6474 } else {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
6501 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) { 6546 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
6502 set_representation(Representation::Tagged()); 6547 set_representation(Representation::Tagged());
6503 SetOperandAt(0, obj); 6548 SetOperandAt(0, obj);
6504 SetOperandAt(1, key); 6549 SetOperandAt(1, key);
6505 SetOperandAt(2, context); 6550 SetOperandAt(2, context);
6506 SetAllSideEffects(); 6551 SetAllSideEffects();
6507 } 6552 }
6508 }; 6553 };
6509 6554
6510 6555
6556 // Indicates whether the store is a store to an entry that was previously
6557 // initialized or not.
6558 enum StoreFieldOrKeyedMode {
6559 INITIALIZING_STORE,
6560 STORE_TO_INITIALIZED_ENTRY
6561 };
6562
6563
6511 class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> { 6564 class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> {
6512 public: 6565 public:
6513 DECLARE_INSTRUCTION_FACTORY_P3(HStoreNamedField, HValue*, 6566 DECLARE_INSTRUCTION_FACTORY_P3(HStoreNamedField, HValue*,
6514 HObjectAccess, HValue*); 6567 HObjectAccess, HValue*);
6568 DECLARE_INSTRUCTION_FACTORY_P4(HStoreNamedField, HValue*,
6569 HObjectAccess, HValue*, StoreFieldOrKeyedMode);
6515 6570
6516 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField) 6571 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
6517 6572
6518 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { 6573 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE {
6519 return index == 1; 6574 return index == 1;
6520 } 6575 }
6521 virtual bool HasOutOfBoundsAccess(int size) V8_OVERRIDE { 6576 virtual bool HasOutOfBoundsAccess(int size) V8_OVERRIDE {
6522 return !access().IsInobject() || access().offset() >= size; 6577 return !access().IsInobject() || access().offset() >= size;
6523 } 6578 }
6524 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 6579 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
6525 if (index == 0 && access().IsExternalMemory()) { 6580 if (index == 0 && access().IsExternalMemory()) {
6526 // object must be external in case of external memory access 6581 // object must be external in case of external memory access
6527 return Representation::External(); 6582 return Representation::External();
6528 } else if (index == 1) { 6583 } else if (index == 1) {
6529 if (field_representation().IsInteger8() || 6584 if (field_representation().IsInteger8() ||
6530 field_representation().IsUInteger8() || 6585 field_representation().IsUInteger8() ||
6531 field_representation().IsInteger16() || 6586 field_representation().IsInteger16() ||
6532 field_representation().IsUInteger16() || 6587 field_representation().IsUInteger16() ||
6533 field_representation().IsInteger32()) { 6588 field_representation().IsInteger32()) {
6534 return Representation::Integer32(); 6589 return Representation::Integer32();
6535 } else if (field_representation().IsDouble() || 6590 } else if (field_representation().IsDouble()) {
6536 field_representation().IsSmi()) { 6591 return field_representation();
6592 } else if (field_representation().IsSmi()) {
6593 if (SmiValuesAre32Bits() && store_mode_ == STORE_TO_INITIALIZED_ENTRY) {
6594 return Representation::Integer32();
6595 }
6537 return field_representation(); 6596 return field_representation();
6538 } else if (field_representation().IsExternal()) { 6597 } else if (field_representation().IsExternal()) {
6539 return Representation::External(); 6598 return Representation::External();
6540 } 6599 }
6541 } 6600 }
6542 return Representation::Tagged(); 6601 return Representation::Tagged();
6543 } 6602 }
6544 virtual void HandleSideEffectDominator(GVNFlag side_effect, 6603 virtual void HandleSideEffectDominator(GVNFlag side_effect,
6545 HValue* dominator) V8_OVERRIDE { 6604 HValue* dominator) V8_OVERRIDE {
6546 ASSERT(side_effect == kChangesNewSpacePromotion); 6605 ASSERT(side_effect == kChangesNewSpacePromotion);
6547 new_space_dominator_ = dominator; 6606 new_space_dominator_ = dominator;
6548 } 6607 }
6549 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 6608 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
6550 6609
6551 void SkipWriteBarrier() { write_barrier_mode_ = SKIP_WRITE_BARRIER; } 6610 void SkipWriteBarrier() { write_barrier_mode_ = SKIP_WRITE_BARRIER; }
6552 bool IsSkipWriteBarrier() const { 6611 bool IsSkipWriteBarrier() const {
6553 return write_barrier_mode_ == SKIP_WRITE_BARRIER; 6612 return write_barrier_mode_ == SKIP_WRITE_BARRIER;
6554 } 6613 }
6555 6614
6556 HValue* object() const { return OperandAt(0); } 6615 HValue* object() const { return OperandAt(0); }
6557 HValue* value() const { return OperandAt(1); } 6616 HValue* value() const { return OperandAt(1); }
6558 HValue* transition() const { return OperandAt(2); } 6617 HValue* transition() const { return OperandAt(2); }
6559 6618
6560 HObjectAccess access() const { return access_; } 6619 HObjectAccess access() const { return access_; }
6561 HValue* new_space_dominator() const { return new_space_dominator_; } 6620 HValue* new_space_dominator() const { return new_space_dominator_; }
6562 bool has_transition() const { return has_transition_; } 6621 bool has_transition() const { return has_transition_; }
6622 StoreFieldOrKeyedMode store_mode() const { return store_mode_; }
6563 6623
6564 Handle<Map> transition_map() const { 6624 Handle<Map> transition_map() const {
6565 if (has_transition()) { 6625 if (has_transition()) {
6566 return Handle<Map>::cast( 6626 return Handle<Map>::cast(
6567 HConstant::cast(transition())->handle(Isolate::Current())); 6627 HConstant::cast(transition())->handle(Isolate::Current()));
6568 } else { 6628 } else {
6569 return Handle<Map>(); 6629 return Handle<Map>();
6570 } 6630 }
6571 } 6631 }
6572 6632
(...skipping 30 matching lines...) Expand all
6603 return access_.representation(); 6663 return access_.representation();
6604 } 6664 }
6605 6665
6606 void UpdateValue(HValue* value) { 6666 void UpdateValue(HValue* value) {
6607 SetOperandAt(1, value); 6667 SetOperandAt(1, value);
6608 } 6668 }
6609 6669
6610 private: 6670 private:
6611 HStoreNamedField(HValue* obj, 6671 HStoreNamedField(HValue* obj,
6612 HObjectAccess access, 6672 HObjectAccess access,
6613 HValue* val) 6673 HValue* val,
6674 StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE)
6614 : access_(access), 6675 : access_(access),
6615 new_space_dominator_(NULL), 6676 new_space_dominator_(NULL),
6616 write_barrier_mode_(UPDATE_WRITE_BARRIER), 6677 write_barrier_mode_(UPDATE_WRITE_BARRIER),
6617 has_transition_(false) { 6678 has_transition_(false),
6679 store_mode_(store_mode) {
6618 SetOperandAt(0, obj); 6680 SetOperandAt(0, obj);
6619 SetOperandAt(1, val); 6681 SetOperandAt(1, val);
6620 SetOperandAt(2, obj); 6682 SetOperandAt(2, obj);
6621 access.SetGVNFlags(this, true); 6683 access.SetGVNFlags(this, true);
6622 } 6684 }
6623 6685
6624 HObjectAccess access_; 6686 HObjectAccess access_;
6625 HValue* new_space_dominator_; 6687 HValue* new_space_dominator_;
6626 WriteBarrierMode write_barrier_mode_ : 1; 6688 WriteBarrierMode write_barrier_mode_ : 1;
6627 bool has_transition_ : 1; 6689 bool has_transition_ : 1;
6690 StoreFieldOrKeyedMode store_mode_ : 1;
6628 }; 6691 };
6629 6692
6630 6693
6631 class HStoreNamedGeneric V8_FINAL : public HTemplateInstruction<3> { 6694 class HStoreNamedGeneric V8_FINAL : public HTemplateInstruction<3> {
6632 public: 6695 public:
6633 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HStoreNamedGeneric, HValue*, 6696 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HStoreNamedGeneric, HValue*,
6634 Handle<String>, HValue*, 6697 Handle<String>, HValue*,
6635 StrictModeFlag); 6698 StrictModeFlag);
6636 HValue* object() { return OperandAt(0); } 6699 HValue* object() { return OperandAt(0); }
6637 HValue* value() { return OperandAt(1); } 6700 HValue* value() { return OperandAt(1); }
(...skipping 26 matching lines...) Expand all
6664 Handle<String> name_; 6727 Handle<String> name_;
6665 StrictModeFlag strict_mode_flag_; 6728 StrictModeFlag strict_mode_flag_;
6666 }; 6729 };
6667 6730
6668 6731
6669 class HStoreKeyed V8_FINAL 6732 class HStoreKeyed V8_FINAL
6670 : public HTemplateInstruction<3>, public ArrayInstructionInterface { 6733 : public HTemplateInstruction<3>, public ArrayInstructionInterface {
6671 public: 6734 public:
6672 DECLARE_INSTRUCTION_FACTORY_P4(HStoreKeyed, HValue*, HValue*, HValue*, 6735 DECLARE_INSTRUCTION_FACTORY_P4(HStoreKeyed, HValue*, HValue*, HValue*,
6673 ElementsKind); 6736 ElementsKind);
6737 DECLARE_INSTRUCTION_FACTORY_P5(HStoreKeyed, HValue*, HValue*, HValue*,
6738 ElementsKind, StoreFieldOrKeyedMode);
6674 6739
6675 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 6740 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
6676 // kind_fast: tagged[int32] = tagged 6741 // kind_fast: tagged[int32] = tagged
6677 // kind_double: tagged[int32] = double 6742 // kind_double: tagged[int32] = double
6678 // kind_smi : tagged[int32] = smi 6743 // kind_smi : tagged[int32] = smi
6679 // kind_external: external[int32] = (double | int32) 6744 // kind_external: external[int32] = (double | int32)
6680 if (index == 0) { 6745 if (index == 0) {
6681 return is_external() ? Representation::External() 6746 return is_external() ? Representation::External()
6682 : Representation::Tagged(); 6747 : Representation::Tagged();
6683 } else if (index == 1) { 6748 } else if (index == 1) {
6684 return ArrayInstructionInterface::KeyedAccessIndexRequirement( 6749 return ArrayInstructionInterface::KeyedAccessIndexRequirement(
6685 OperandAt(1)->representation()); 6750 OperandAt(1)->representation());
6686 } 6751 }
6687 6752
6688 ASSERT_EQ(index, 2); 6753 ASSERT_EQ(index, 2);
6689 if (IsDoubleOrFloatElementsKind(elements_kind())) { 6754 if (IsDoubleOrFloatElementsKind(elements_kind())) {
6690 return Representation::Double(); 6755 return Representation::Double();
6691 } 6756 }
6692 6757 if (SmiValuesAre32Bits() && store_mode_ == STORE_TO_INITIALIZED_ENTRY) {
6758 return Representation::Integer32();
6759 }
6693 if (IsFastSmiElementsKind(elements_kind())) { 6760 if (IsFastSmiElementsKind(elements_kind())) {
6694 return Representation::Smi(); 6761 return Representation::Smi();
6695 } 6762 }
6696 6763
6697 return is_external() ? Representation::Integer32() 6764 return is_external() ? Representation::Integer32()
6698 : Representation::Tagged(); 6765 : Representation::Tagged();
6699 } 6766 }
6700 6767
6701 bool is_external() const { 6768 bool is_external() const {
6702 return IsExternalArrayElementsKind(elements_kind()); 6769 return IsExternalArrayElementsKind(elements_kind());
6703 } 6770 }
6704 6771
6705 virtual Representation observed_input_representation(int index) V8_OVERRIDE { 6772 virtual Representation observed_input_representation(int index) V8_OVERRIDE {
6706 if (index < 2) return RequiredInputRepresentation(index); 6773 if (index < 2) return RequiredInputRepresentation(index);
6707 if (IsUninitialized()) { 6774 if (IsUninitialized()) {
6708 return Representation::None(); 6775 return Representation::None();
6709 } 6776 }
6777 if (IsDoubleOrFloatElementsKind(elements_kind())) {
6778 return Representation::Double();
6779 }
6780 if (SmiValuesAre32Bits() && store_mode_ == STORE_TO_INITIALIZED_ENTRY) {
6781 return Representation::Integer32();
6782 }
6710 if (IsFastSmiElementsKind(elements_kind())) { 6783 if (IsFastSmiElementsKind(elements_kind())) {
6711 return Representation::Smi(); 6784 return Representation::Smi();
6712 } 6785 }
6713 if (IsDoubleOrFloatElementsKind(elements_kind())) {
6714 return Representation::Double();
6715 }
6716 if (is_external()) { 6786 if (is_external()) {
6717 return Representation::Integer32(); 6787 return Representation::Integer32();
6718 } 6788 }
6719 // For fast object elements kinds, don't assume anything. 6789 // For fast object elements kinds, don't assume anything.
6720 return Representation::None(); 6790 return Representation::None();
6721 } 6791 }
6722 6792
6723 HValue* elements() { return OperandAt(0); } 6793 HValue* elements() { return OperandAt(0); }
6724 HValue* key() { return OperandAt(1); } 6794 HValue* key() { return OperandAt(1); }
6725 HValue* value() { return OperandAt(2); } 6795 HValue* value() { return OperandAt(2); }
6726 bool value_is_smi() const { 6796 bool value_is_smi() const {
6727 return IsFastSmiElementsKind(elements_kind_); 6797 return IsFastSmiElementsKind(elements_kind_);
6728 } 6798 }
6799 StoreFieldOrKeyedMode store_mode() const { return store_mode_; }
6729 ElementsKind elements_kind() const { return elements_kind_; } 6800 ElementsKind elements_kind() const { return elements_kind_; }
6730 uint32_t index_offset() { return index_offset_; } 6801 uint32_t index_offset() { return index_offset_; }
6731 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } 6802 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
6732 virtual int MaxIndexOffsetBits() { 6803 virtual int MaxIndexOffsetBits() {
6733 return 31 - ElementsKindToShiftSize(elements_kind_); 6804 return 31 - ElementsKindToShiftSize(elements_kind_);
6734 } 6805 }
6735 HValue* GetKey() { return key(); } 6806 HValue* GetKey() { return key(); }
6736 void SetKey(HValue* key) { SetOperandAt(1, key); } 6807 void SetKey(HValue* key) { SetOperandAt(1, key); }
6737 bool IsDehoisted() { return is_dehoisted_; } 6808 bool IsDehoisted() { return is_dehoisted_; }
6738 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } 6809 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
(...skipping 25 matching lines...) Expand all
6764 } 6835 }
6765 6836
6766 bool NeedsCanonicalization(); 6837 bool NeedsCanonicalization();
6767 6838
6768 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 6839 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
6769 6840
6770 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed) 6841 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed)
6771 6842
6772 private: 6843 private:
6773 HStoreKeyed(HValue* obj, HValue* key, HValue* val, 6844 HStoreKeyed(HValue* obj, HValue* key, HValue* val,
6774 ElementsKind elements_kind) 6845 ElementsKind elements_kind,
6846 StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE)
6775 : elements_kind_(elements_kind), 6847 : elements_kind_(elements_kind),
6776 index_offset_(0), 6848 index_offset_(0),
6777 is_dehoisted_(false), 6849 is_dehoisted_(false),
6778 is_uninitialized_(false), 6850 is_uninitialized_(false),
6851 store_mode_(store_mode),
6779 new_space_dominator_(NULL) { 6852 new_space_dominator_(NULL) {
6780 SetOperandAt(0, obj); 6853 SetOperandAt(0, obj);
6781 SetOperandAt(1, key); 6854 SetOperandAt(1, key);
6782 SetOperandAt(2, val); 6855 SetOperandAt(2, val);
6783 6856
6857 ASSERT(store_mode != STORE_TO_INITIALIZED_ENTRY ||
6858 elements_kind == FAST_SMI_ELEMENTS);
6859
6784 if (IsFastObjectElementsKind(elements_kind)) { 6860 if (IsFastObjectElementsKind(elements_kind)) {
6785 SetFlag(kTrackSideEffectDominators); 6861 SetFlag(kTrackSideEffectDominators);
6786 SetGVNFlag(kDependsOnNewSpacePromotion); 6862 SetGVNFlag(kDependsOnNewSpacePromotion);
6787 } 6863 }
6788 if (is_external()) { 6864 if (is_external()) {
6789 SetGVNFlag(kChangesExternalMemory); 6865 SetGVNFlag(kChangesExternalMemory);
6790 SetFlag(kAllowUndefinedAsNaN); 6866 SetFlag(kAllowUndefinedAsNaN);
6791 } else if (IsFastDoubleElementsKind(elements_kind)) { 6867 } else if (IsFastDoubleElementsKind(elements_kind)) {
6792 SetGVNFlag(kChangesDoubleArrayElements); 6868 SetGVNFlag(kChangesDoubleArrayElements);
6793 } else if (IsFastSmiElementsKind(elements_kind)) { 6869 } else if (IsFastSmiElementsKind(elements_kind)) {
6794 SetGVNFlag(kChangesArrayElements); 6870 SetGVNFlag(kChangesArrayElements);
6795 } else { 6871 } else {
6796 SetGVNFlag(kChangesArrayElements); 6872 SetGVNFlag(kChangesArrayElements);
6797 } 6873 }
6798 6874
6799 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. 6875 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating.
6800 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS && 6876 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS &&
6801 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) { 6877 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) {
6802 SetFlag(kTruncatingToInt32); 6878 SetFlag(kTruncatingToInt32);
6803 } 6879 }
6804 } 6880 }
6805 6881
6806 ElementsKind elements_kind_; 6882 ElementsKind elements_kind_;
6807 uint32_t index_offset_; 6883 uint32_t index_offset_;
6808 bool is_dehoisted_ : 1; 6884 bool is_dehoisted_ : 1;
6809 bool is_uninitialized_ : 1; 6885 bool is_uninitialized_ : 1;
6886 StoreFieldOrKeyedMode store_mode_: 1;
6810 HValue* new_space_dominator_; 6887 HValue* new_space_dominator_;
6811 }; 6888 };
6812 6889
6813 6890
6814 class HStoreKeyedGeneric V8_FINAL : public HTemplateInstruction<4> { 6891 class HStoreKeyedGeneric V8_FINAL : public HTemplateInstruction<4> {
6815 public: 6892 public:
6816 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HStoreKeyedGeneric, HValue*, 6893 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HStoreKeyedGeneric, HValue*,
6817 HValue*, HValue*, StrictModeFlag); 6894 HValue*, HValue*, StrictModeFlag);
6818 6895
6819 HValue* object() { return OperandAt(0); } 6896 HValue* object() { return OperandAt(0); }
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
6908 ElementsKind to_kind_; 6985 ElementsKind to_kind_;
6909 }; 6986 };
6910 6987
6911 6988
6912 class HStringAdd V8_FINAL : public HBinaryOperation { 6989 class HStringAdd V8_FINAL : public HBinaryOperation {
6913 public: 6990 public:
6914 static HInstruction* New(Zone* zone, 6991 static HInstruction* New(Zone* zone,
6915 HValue* context, 6992 HValue* context,
6916 HValue* left, 6993 HValue* left,
6917 HValue* right, 6994 HValue* right,
6918 StringAddFlags flags = STRING_ADD_CHECK_NONE); 6995 PretenureFlag pretenure_flag = NOT_TENURED,
6996 StringAddFlags flags = STRING_ADD_CHECK_BOTH,
6997 Handle<AllocationSite> allocation_site =
6998 Handle<AllocationSite>::null());
6919 6999
6920 StringAddFlags flags() const { return flags_; } 7000 StringAddFlags flags() const { return flags_; }
7001 PretenureFlag pretenure_flag() const { return pretenure_flag_; }
6921 7002
6922 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 7003 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
6923 return Representation::Tagged(); 7004 return Representation::Tagged();
6924 } 7005 }
6925 7006
7007 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
7008
6926 DECLARE_CONCRETE_INSTRUCTION(StringAdd) 7009 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
6927 7010
6928 protected: 7011 protected:
6929 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } 7012 virtual bool DataEquals(HValue* other) V8_OVERRIDE {
7013 return flags_ == HStringAdd::cast(other)->flags_ &&
7014 pretenure_flag_ == HStringAdd::cast(other)->pretenure_flag_;
7015 }
6930 7016
6931 private: 7017 private:
6932 HStringAdd(HValue* context, HValue* left, HValue* right, StringAddFlags flags) 7018 HStringAdd(HValue* context,
6933 : HBinaryOperation(context, left, right, HType::String()), flags_(flags) { 7019 HValue* left,
7020 HValue* right,
7021 PretenureFlag pretenure_flag,
7022 StringAddFlags flags,
7023 Handle<AllocationSite> allocation_site)
7024 : HBinaryOperation(context, left, right, HType::String()),
7025 flags_(flags), pretenure_flag_(pretenure_flag) {
6934 set_representation(Representation::Tagged()); 7026 set_representation(Representation::Tagged());
6935 if (MightHaveSideEffects()) { 7027 SetFlag(kUseGVN);
6936 SetAllSideEffects(); 7028 SetGVNFlag(kDependsOnMaps);
6937 } else { 7029 SetGVNFlag(kChangesNewSpacePromotion);
6938 SetFlag(kUseGVN); 7030 if (FLAG_trace_pretenuring) {
6939 SetGVNFlag(kDependsOnMaps); 7031 PrintF("HStringAdd with AllocationSite %p %s\n",
6940 SetGVNFlag(kChangesNewSpacePromotion); 7032 allocation_site.is_null()
7033 ? static_cast<void*>(NULL)
7034 : static_cast<void*>(*allocation_site),
7035 pretenure_flag == TENURED ? "tenured" : "not tenured");
6941 } 7036 }
6942 } 7037 }
6943 7038
6944 bool MightHaveSideEffects() const {
6945 return flags_ != STRING_ADD_CHECK_NONE &&
6946 (left()->ToStringCanBeObserved() || right()->ToStringCanBeObserved());
6947 }
6948
6949 // No side-effects except possible allocation: 7039 // No side-effects except possible allocation:
6950 // NOTE: this instruction does not call ToString() on its inputs, when flags_ 7040 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
6951 // is set to STRING_ADD_CHECK_NONE.
6952 virtual bool IsDeletable() const V8_OVERRIDE {
6953 return !MightHaveSideEffects();
6954 }
6955 7041
6956 const StringAddFlags flags_; 7042 const StringAddFlags flags_;
7043 const PretenureFlag pretenure_flag_;
6957 }; 7044 };
6958 7045
6959 7046
6960 class HStringCharCodeAt V8_FINAL : public HTemplateInstruction<3> { 7047 class HStringCharCodeAt V8_FINAL : public HTemplateInstruction<3> {
6961 public: 7048 public:
6962 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HStringCharCodeAt, 7049 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HStringCharCodeAt,
6963 HValue*, 7050 HValue*,
6964 HValue*); 7051 HValue*);
6965 7052
6966 virtual Representation RequiredInputRepresentation(int index) { 7053 virtual Representation RequiredInputRepresentation(int index) {
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after
7489 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 7576 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
7490 }; 7577 };
7491 7578
7492 7579
7493 #undef DECLARE_INSTRUCTION 7580 #undef DECLARE_INSTRUCTION
7494 #undef DECLARE_CONCRETE_INSTRUCTION 7581 #undef DECLARE_CONCRETE_INSTRUCTION
7495 7582
7496 } } // namespace v8::internal 7583 } } // namespace v8::internal
7497 7584
7498 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 7585 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW
« no previous file with comments | « src/hydrogen-gvn.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698