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

Side by Side Diff: runtime/vm/object.h

Issue 509153003: New bigint implementation in the vm. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #ifndef VM_OBJECT_H_ 5 #ifndef VM_OBJECT_H_
6 #define VM_OBJECT_H_ 6 #define VM_OBJECT_H_
7 7
8 #include "include/dart_api.h" 8 #include "include/dart_api.h"
9 #include "platform/assert.h" 9 #include "platform/assert.h"
10 #include "platform/utils.h" 10 #include "platform/utils.h"
(...skipping 1012 matching lines...) Expand 10 before | Expand all | Expand 10 after
1023 intptr_t FindClosureIndex(const Function& function) const; 1023 intptr_t FindClosureIndex(const Function& function) const;
1024 RawFunction* ClosureFunctionFromIndex(intptr_t idx) const; 1024 RawFunction* ClosureFunctionFromIndex(intptr_t idx) const;
1025 1025
1026 RawFunction* LookupDynamicFunction(const String& name) const; 1026 RawFunction* LookupDynamicFunction(const String& name) const;
1027 RawFunction* LookupDynamicFunctionAllowPrivate(const String& name) const; 1027 RawFunction* LookupDynamicFunctionAllowPrivate(const String& name) const;
1028 RawFunction* LookupStaticFunction(const String& name) const; 1028 RawFunction* LookupStaticFunction(const String& name) const;
1029 RawFunction* LookupStaticFunctionAllowPrivate(const String& name) const; 1029 RawFunction* LookupStaticFunctionAllowPrivate(const String& name) const;
1030 RawFunction* LookupConstructor(const String& name) const; 1030 RawFunction* LookupConstructor(const String& name) const;
1031 RawFunction* LookupConstructorAllowPrivate(const String& name) const; 1031 RawFunction* LookupConstructorAllowPrivate(const String& name) const;
1032 RawFunction* LookupFactory(const String& name) const; 1032 RawFunction* LookupFactory(const String& name) const;
1033 RawFunction* LookupFactoryAllowPrivate(const String& name) const;
1033 RawFunction* LookupFunction(const String& name) const; 1034 RawFunction* LookupFunction(const String& name) const;
1034 RawFunction* LookupFunctionAllowPrivate(const String& name) const; 1035 RawFunction* LookupFunctionAllowPrivate(const String& name) const;
1035 RawFunction* LookupGetterFunction(const String& name) const; 1036 RawFunction* LookupGetterFunction(const String& name) const;
1036 RawFunction* LookupSetterFunction(const String& name) const; 1037 RawFunction* LookupSetterFunction(const String& name) const;
1037 RawFunction* LookupFunctionAtToken(intptr_t token_pos) const; 1038 RawFunction* LookupFunctionAtToken(intptr_t token_pos) const;
1038 RawField* LookupInstanceField(const String& name) const; 1039 RawField* LookupInstanceField(const String& name) const;
1039 RawField* LookupStaticField(const String& name) const; 1040 RawField* LookupStaticField(const String& name) const;
1040 RawField* LookupField(const String& name) const; 1041 RawField* LookupField(const String& name) const;
1041 1042
1042 RawLibraryPrefix* LookupLibraryPrefix(const String& name) const; 1043 RawLibraryPrefix* LookupLibraryPrefix(const String& name) const;
(...skipping 4057 matching lines...) Expand 10 before | Expand all | Expand 10 after
5100 5101
5101 private: 5102 private:
5102 OBJECT_IMPLEMENTATION(Number, Instance); 5103 OBJECT_IMPLEMENTATION(Number, Instance);
5103 friend class Class; 5104 friend class Class;
5104 }; 5105 };
5105 5106
5106 5107
5107 class Integer : public Number { 5108 class Integer : public Number {
5108 public: 5109 public:
5109 static RawInteger* New(const String& str, Heap::Space space = Heap::kNew); 5110 static RawInteger* New(const String& str, Heap::Space space = Heap::kNew);
5110 static RawInteger* NewFromUint64( 5111 static RawInteger* NewFromUint64(uint64_t value,
5111 uint64_t value, Heap::Space space = Heap::kNew); 5112 Heap::Space space = Heap::kNew);
5112 5113
5113 // Returns a canonical Integer object allocated in the old gen space. 5114 // Returns a canonical Integer object allocated in the old gen space.
5114 static RawInteger* NewCanonical(const String& str); 5115 static RawInteger* NewCanonical(const String& str);
5115 5116
5116 // Do not throw JavascriptIntegerOverflow if 'silent' is true. 5117 // Do not throw JavascriptIntegerOverflow if 'silent' is true.
5117 static RawInteger* New(int64_t value, 5118 static RawInteger* New(int64_t value,
5118 Heap::Space space = Heap::kNew, 5119 Heap::Space space = Heap::kNew,
5119 const bool silent = false); 5120 const bool silent = false);
5120 5121
5121 virtual bool OperatorEquals(const Instance& other) const { 5122 virtual bool OperatorEquals(const Instance& other) const {
5122 return Equals(other); 5123 return Equals(other);
5123 } 5124 }
5124 virtual bool CanonicalizeEquals(const Instance& other) const { 5125 virtual bool CanonicalizeEquals(const Instance& other) const {
5125 return Equals(other); 5126 return Equals(other);
5126 } 5127 }
5127 virtual bool Equals(const Instance& other) const { 5128 virtual bool Equals(const Instance& other) const;
5128 UNREACHABLE();
5129 return false;
5130 }
5131 5129
5132 virtual RawObject* HashCode() const { return raw(); } 5130 virtual RawObject* HashCode() const { return raw(); }
5133 5131
5134 // Integer is an abstract class. 5132 virtual bool IsZero() const;
5135 virtual bool IsZero() const { 5133 virtual bool IsNegative() const;
5136 UNREACHABLE(); 5134
5137 return false;
5138 }
5139 virtual bool IsNegative() const {
5140 // Number is an abstract class.
5141 UNREACHABLE();
5142 return false;
5143 }
5144 virtual double AsDoubleValue() const; 5135 virtual double AsDoubleValue() const;
5145 virtual int64_t AsInt64Value() const; 5136 virtual int64_t AsInt64Value() const;
5146 virtual uint32_t AsTruncatedUint32Value() const; 5137 virtual uint32_t AsTruncatedUint32Value() const;
5147 5138
5139 virtual bool FitsIntoSmi() const;
5140
5148 // Returns 0, -1 or 1. 5141 // Returns 0, -1 or 1.
5149 virtual int CompareWith(const Integer& other) const; 5142 virtual int CompareWith(const Integer& other) const;
5150 5143
5151 // Return the most compact presentation of an integer. 5144 // Return the most compact presentation of an integer.
5152 RawInteger* AsValidInteger() const; 5145 RawInteger* AsValidInteger() const;
5153 5146
5147 // Returns null to indicate that a bigint operation is required.
5154 RawInteger* ArithmeticOp(Token::Kind operation, const Integer& other) const; 5148 RawInteger* ArithmeticOp(Token::Kind operation, const Integer& other) const;
5155 RawInteger* BitOp(Token::Kind operation, const Integer& other) const; 5149 RawInteger* BitOp(Token::Kind operation, const Integer& other) const;
5156 5150
5157 // Returns true if the Integer does not fit in a Javascript integer. 5151 // Returns true if the Integer does not fit in a Javascript integer.
5158 bool CheckJavascriptIntegerOverflow() const; 5152 bool CheckJavascriptIntegerOverflow() const;
5159 5153
5160 private: 5154 private:
5161 // Return an integer in the form of a RawBigint.
5162 RawBigint* AsBigint() const;
5163
5164 OBJECT_IMPLEMENTATION(Integer, Number); 5155 OBJECT_IMPLEMENTATION(Integer, Number);
5165 friend class Class; 5156 friend class Class;
5166 }; 5157 };
5167 5158
5168 5159
5169 class Smi : public Integer { 5160 class Smi : public Integer {
5170 public: 5161 public:
5171 static const intptr_t kBits = kSmiBits; 5162 static const intptr_t kBits = kSmiBits;
5172 static const intptr_t kMaxValue = kSmiMax; 5163 static const intptr_t kMaxValue = kSmiMax;
5173 static const intptr_t kMinValue = kSmiMin; 5164 static const intptr_t kMinValue = kSmiMin;
5174 5165
5175 intptr_t Value() const { 5166 intptr_t Value() const {
5176 return ValueFromRaw(raw_value()); 5167 return ValueFromRaw(raw_value());
5177 } 5168 }
5178 5169
5179 virtual bool Equals(const Instance& other) const; 5170 virtual bool Equals(const Instance& other) const;
5180 virtual bool IsZero() const { return Value() == 0; } 5171 virtual bool IsZero() const { return Value() == 0; }
5181 virtual bool IsNegative() const { return Value() < 0; } 5172 virtual bool IsNegative() const { return Value() < 0; }
5182 // Smi values are implicitly canonicalized. 5173 // Smi values are implicitly canonicalized.
5183 virtual RawInstance* CheckAndCanonicalize(const char** error_str) const { 5174 virtual RawInstance* CheckAndCanonicalize(const char** error_str) const {
5184 return reinterpret_cast<RawSmi*>(raw_value()); 5175 return reinterpret_cast<RawSmi*>(raw_value());
5185 } 5176 }
5186 5177
5187 virtual double AsDoubleValue() const; 5178 virtual double AsDoubleValue() const;
5188 virtual int64_t AsInt64Value() const; 5179 virtual int64_t AsInt64Value() const;
5189 virtual uint32_t AsTruncatedUint32Value() const; 5180 virtual uint32_t AsTruncatedUint32Value() const;
5190 5181
5182 virtual bool FitsIntoSmi() const { return true; }
5183
5191 virtual int CompareWith(const Integer& other) const; 5184 virtual int CompareWith(const Integer& other) const;
5192 5185
5193 static intptr_t InstanceSize() { return 0; } 5186 static intptr_t InstanceSize() { return 0; }
5194 5187
5195 static RawSmi* New(intptr_t value) { 5188 static RawSmi* New(intptr_t value) {
5196 intptr_t raw_smi = (value << kSmiTagShift) | kSmiTag; 5189 intptr_t raw_smi = (value << kSmiTagShift) | kSmiTag;
5197 ASSERT(ValueFromRaw(raw_smi) == value); 5190 ASSERT(ValueFromRaw(raw_smi) == value);
5198 return reinterpret_cast<RawSmi*>(raw_smi); 5191 return reinterpret_cast<RawSmi*>(raw_smi);
5199 } 5192 }
5200 5193
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
5267 virtual bool IsNegative() const { 5260 virtual bool IsNegative() const {
5268 return value() < 0; 5261 return value() < 0;
5269 } 5262 }
5270 5263
5271 virtual bool Equals(const Instance& other) const; 5264 virtual bool Equals(const Instance& other) const;
5272 5265
5273 virtual double AsDoubleValue() const; 5266 virtual double AsDoubleValue() const;
5274 virtual int64_t AsInt64Value() const; 5267 virtual int64_t AsInt64Value() const;
5275 virtual uint32_t AsTruncatedUint32Value() const; 5268 virtual uint32_t AsTruncatedUint32Value() const;
5276 5269
5270 virtual bool FitsIntoSmi() const;
5271
5277 virtual int CompareWith(const Integer& other) const; 5272 virtual int CompareWith(const Integer& other) const;
5278 5273
5279 static intptr_t InstanceSize() { 5274 static intptr_t InstanceSize() {
5280 return RoundedAllocationSize(sizeof(RawMint)); 5275 return RoundedAllocationSize(sizeof(RawMint));
5281 } 5276 }
5282 5277
5283 protected: 5278 protected:
5284 // Only Integer::NewXXX is allowed to call Mint::NewXXX directly. 5279 // Only Integer::NewXXX is allowed to call Mint::NewXXX directly.
5285 friend class Integer; 5280 friend class Integer;
5286 5281
5287 static RawMint* New(int64_t value, Heap::Space space = Heap::kNew); 5282 static RawMint* New(int64_t value, Heap::Space space = Heap::kNew);
5288 5283
5289 static RawMint* NewCanonical(int64_t value); 5284 static RawMint* NewCanonical(int64_t value);
5290 5285
5291 private: 5286 private:
5292 void set_value(int64_t value) const; 5287 void set_value(int64_t value) const;
5293 5288
5294 FINAL_HEAP_OBJECT_IMPLEMENTATION(Mint, Integer); 5289 FINAL_HEAP_OBJECT_IMPLEMENTATION(Mint, Integer);
5295 friend class Class; 5290 friend class Class;
5296 }; 5291 };
5297 5292
5298 5293
5299 class Bigint : public Integer { 5294 class Bigint : public Integer {
5300 private:
5301 typedef uint32_t Chunk;
5302 typedef uint64_t DoubleChunk;
5303 static const int kChunkSize = sizeof(Chunk);
5304
5305 public: 5295 public:
5306 virtual bool IsZero() const { return raw_ptr()->signed_length_ == 0; } 5296 virtual bool IsZero() const { return Used() == 0;}
5307 virtual bool IsNegative() const { return raw_ptr()->signed_length_ < 0; } 5297 virtual bool IsNegative() const { return Neg(); }
5308
5309 virtual bool Equals(const Instance& other) const; 5298 virtual bool Equals(const Instance& other) const;
5310 5299
5311 virtual double AsDoubleValue() const; 5300 virtual double AsDoubleValue() const;
5312 virtual int64_t AsInt64Value() const; 5301 virtual int64_t AsInt64Value() const;
5313 virtual uint32_t AsTruncatedUint32Value() const; 5302 virtual uint32_t AsTruncatedUint32Value() const;
5314 5303
5315 virtual int CompareWith(const Integer& other) const; 5304 virtual int CompareWith(const Integer& other) const;
5316 5305
5317 static const intptr_t kBytesPerElement = kChunkSize; 5306 virtual bool CheckAndCanonicalizeFields(const char** error_str) const;
5318 static const intptr_t kMaxElements = kSmiMax / kBytesPerElement;
5319 5307
5320 static intptr_t InstanceSize() { return 0; } 5308 virtual bool FitsIntoSmi() const;
5309 bool FitsIntoInt64() const;
5310 bool FitsIntoUint64() const;
5311 uint64_t AsUint64Value() const;
5321 5312
5322 static intptr_t InstanceSize(intptr_t len) { 5313 static intptr_t InstanceSize() {
5323 ASSERT(0 <= len && len <= kMaxElements); 5314 return RoundedAllocationSize(sizeof(RawBigint));
5324 return RoundedAllocationSize(sizeof(RawBigint) + (len * kBytesPerElement));
5325 } 5315 }
5326 5316
5327 protected: 5317 // Accessors used by native calls from Dart.
5328 // Only Integer::NewXXX is allowed to call Bigint::NewXXX directly. 5318 RawBool* neg() const { return raw_ptr()->neg_; }
5329 friend class Integer; 5319 void set_neg(const Bool& value) const;
5320 static intptr_t neg_offset() { return OFFSET_OF(RawBigint, neg_); }
5321 RawSmi* used() const { return raw_ptr()->used_; }
5322 void set_used(const Smi& value) const;
5323 static intptr_t used_offset() { return OFFSET_OF(RawBigint, used_); }
5324 RawTypedData* digits() const { return raw_ptr()->digits_; }
5325 void set_digits(const TypedData& value) const;
5326 static intptr_t digits_offset() { return OFFSET_OF(RawBigint, digits_); }
5330 5327
5331 RawBigint* BigArithmeticOp(Token::Kind operation, const Bigint& other) const; 5328 // Accessors used by runtime calls from C++.
5329 bool Neg() const;
5330 void SetNeg(bool value) const;
5331 intptr_t Used() const;
5332 void SetUsed(intptr_t value) const;
5333 uint32_t DigitAt(intptr_t index) const;
5334 void SetDigitAt(intptr_t index, uint32_t value) const;
5332 5335
5333 static RawBigint* New(const String& str, Heap::Space space = Heap::kNew); 5336 const char* ToDecCString(uword (*allocator)(intptr_t size)) const;
5337 const char* ToHexCString(uword (*allocator)(intptr_t size)) const;
5338
5339 static const intptr_t kExtraDigits = 4; // Same as _Bigint.EXTRA_DIGITS
5340 static const intptr_t kBitsPerDigit = 32; // Same as _Bigint.DIGIT_BITS
5341 static const int64_t kDigitBase = 1LL << kBitsPerDigit;
5342 static const int64_t kDigitMask = kDigitBase - 1;
5343
5344 static RawBigint* New(Heap::Space space = Heap::kNew);
5345
5346 static RawBigint* NewFromInt64(int64_t value,
5347 Heap::Space space = Heap::kNew);
5348
5349 static RawBigint* NewFromUint64(uint64_t value,
5350 Heap::Space space = Heap::kNew);
5351
5352 static RawBigint* NewFromShiftedInt64(int64_t value, intptr_t shift,
5353 Heap::Space space = Heap::kNew);
5354
5355 static RawBigint* NewFromCString(const char* str,
5356 Heap::Space space = Heap::kNew);
5334 5357
5335 // Returns a canonical Bigint object allocated in the old gen space. 5358 // Returns a canonical Bigint object allocated in the old gen space.
5336 static RawBigint* NewCanonical(const String& str); 5359 static RawBigint* NewCanonical(const String& str);
5337 5360
5338 private: 5361 private:
5339 Chunk GetChunkAt(intptr_t i) const { 5362 static RawBigint* NewFromHexCString(const char* str,
5340 return *ChunkAddr(i); 5363 Heap::Space space = Heap::kNew);
5341 } 5364 static RawBigint* NewFromDecCString(const char* str,
5365 Heap::Space space = Heap::kNew);
5342 5366
5343 void SetChunkAt(intptr_t i, Chunk newValue) const { 5367 // Make sure at least 'length' _digits are allocated.
5344 *ChunkAddr(i) = newValue; 5368 // Copy existing _digits if reallocation is necessary.
5345 } 5369 void EnsureLength(intptr_t length, Heap::Space space = Heap::kNew) const;
5346 5370
5347 // Returns the number of chunks in use. 5371 // Do not count zero high digits as used.
5348 intptr_t Length() const { 5372 void Clamp() const;
5349 intptr_t signed_length = raw_ptr()->signed_length_;
5350 return Utils::Abs(signed_length);
5351 }
5352 5373
5353 // SetLength does not change the sign. 5374 bool IsClamped() const;
5354 void SetLength(intptr_t length) const {
5355 ASSERT(length >= 0);
5356 bool is_negative = IsNegative();
5357 raw_ptr()->signed_length_ = length;
5358 if (is_negative) ToggleSign();
5359 }
5360
5361 void SetSign(bool is_negative) const {
5362 if (is_negative != IsNegative()) {
5363 ToggleSign();
5364 }
5365 }
5366
5367 void ToggleSign() const {
5368 raw_ptr()->signed_length_ = -raw_ptr()->signed_length_;
5369 }
5370
5371 Chunk* ChunkAddr(intptr_t index) const {
5372 ASSERT(0 <= index);
5373 ASSERT(index < Length());
5374 uword digits_start = reinterpret_cast<uword>(raw_ptr()) + sizeof(RawBigint);
5375 return &(reinterpret_cast<Chunk*>(digits_start)[index]);
5376 }
5377 5375
5378 static RawBigint* Allocate(intptr_t length, Heap::Space space = Heap::kNew); 5376 static RawBigint* Allocate(intptr_t length, Heap::Space space = Heap::kNew);
5379 5377
5380 FINAL_HEAP_OBJECT_IMPLEMENTATION(Bigint, Integer); 5378 FINAL_HEAP_OBJECT_IMPLEMENTATION(Bigint, Integer);
5381 friend class BigintOperations;
5382 friend class Class; 5379 friend class Class;
5383 }; 5380 };
5384 5381
5385 5382
5386 // Class Double represents class Double in corelib_impl, which implements 5383 // Class Double represents class Double in corelib_impl, which implements
5387 // abstract class double in corelib. 5384 // abstract class double in corelib.
5388 class Double : public Number { 5385 class Double : public Number {
5389 public: 5386 public:
5390 double value() const { 5387 double value() const {
5391 return raw_ptr()->value_; 5388 return raw_ptr()->value_;
(...skipping 1193 matching lines...) Expand 10 before | Expand all | Expand 10 after
6585 intptr_t cid = raw()->GetClassId(); 6582 intptr_t cid = raw()->GetClassId();
6586 return (ElementSizeInBytes(cid) * Length()); 6583 return (ElementSizeInBytes(cid) * Length());
6587 } 6584 }
6588 6585
6589 void* DataAddr(intptr_t byte_offset) const { 6586 void* DataAddr(intptr_t byte_offset) const {
6590 ASSERT((byte_offset == 0) || 6587 ASSERT((byte_offset == 0) ||
6591 ((byte_offset > 0) && (byte_offset < LengthInBytes()))); 6588 ((byte_offset > 0) && (byte_offset < LengthInBytes())));
6592 return reinterpret_cast<void*>(raw_ptr()->data() + byte_offset); 6589 return reinterpret_cast<void*>(raw_ptr()->data() + byte_offset);
6593 } 6590 }
6594 6591
6592 virtual bool CanonicalizeEquals(const Instance& other) const;
6593
6595 #define TYPED_GETTER_SETTER(name, type) \ 6594 #define TYPED_GETTER_SETTER(name, type) \
6596 type Get##name(intptr_t byte_offset) const { \ 6595 type Get##name(intptr_t byte_offset) const { \
6597 return *reinterpret_cast<type*>(DataAddr(byte_offset)); \ 6596 return *reinterpret_cast<type*>(DataAddr(byte_offset)); \
6598 } \ 6597 } \
6599 void Set##name(intptr_t byte_offset, type value) const { \ 6598 void Set##name(intptr_t byte_offset, type value) const { \
6600 *reinterpret_cast<type*>(DataAddr(byte_offset)) = value; \ 6599 *reinterpret_cast<type*>(DataAddr(byte_offset)) = value; \
6601 } 6600 }
6602 TYPED_GETTER_SETTER(Int8, int8_t) 6601 TYPED_GETTER_SETTER(Int8, int8_t)
6603 TYPED_GETTER_SETTER(Uint8, uint8_t) 6602 TYPED_GETTER_SETTER(Uint8, uint8_t)
6604 TYPED_GETTER_SETTER(Int16, int16_t) 6603 TYPED_GETTER_SETTER(Int16, int16_t)
(...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after
7417 7416
7418 7417
7419 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, 7418 RawObject* MegamorphicCache::GetTargetFunction(const Array& array,
7420 intptr_t index) { 7419 intptr_t index) {
7421 return array.At((index * kEntryLength) + kTargetFunctionIndex); 7420 return array.At((index * kEntryLength) + kTargetFunctionIndex);
7422 } 7421 }
7423 7422
7424 } // namespace dart 7423 } // namespace dart
7425 7424
7426 #endif // VM_OBJECT_H_ 7425 #endif // VM_OBJECT_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698