| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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_ |
| OLD | NEW |