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

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 4060 matching lines...) Expand 10 before | Expand all | Expand 10 after
5103 5104
5104 private: 5105 private:
5105 OBJECT_IMPLEMENTATION(Number, Instance); 5106 OBJECT_IMPLEMENTATION(Number, Instance);
5106 friend class Class; 5107 friend class Class;
5107 }; 5108 };
5108 5109
5109 5110
5110 class Integer : public Number { 5111 class Integer : public Number {
5111 public: 5112 public:
5112 static RawInteger* New(const String& str, Heap::Space space = Heap::kNew); 5113 static RawInteger* New(const String& str, Heap::Space space = Heap::kNew);
5113 static RawInteger* NewFromUint64( 5114 static RawInteger* NewFromUint64(uint64_t value,
5114 uint64_t value, Heap::Space space = Heap::kNew); 5115 Heap::Space space = Heap::kNew);
5115 5116
5116 // Returns a canonical Integer object allocated in the old gen space. 5117 // Returns a canonical Integer object allocated in the old gen space.
5117 static RawInteger* NewCanonical(const String& str); 5118 static RawInteger* NewCanonical(const String& str);
5118 5119
5119 // Do not throw JavascriptIntegerOverflow if 'silent' is true. 5120 // Do not throw JavascriptIntegerOverflow if 'silent' is true.
5120 static RawInteger* New(int64_t value, 5121 static RawInteger* New(int64_t value,
5121 Heap::Space space = Heap::kNew, 5122 Heap::Space space = Heap::kNew,
5122 const bool silent = false); 5123 const bool silent = false);
5123 5124
5124 virtual bool OperatorEquals(const Instance& other) const { 5125 virtual bool OperatorEquals(const Instance& other) const {
5125 return Equals(other); 5126 return Equals(other);
5126 } 5127 }
5127 virtual bool CanonicalizeEquals(const Instance& other) const { 5128 virtual bool CanonicalizeEquals(const Instance& other) const {
5128 return Equals(other); 5129 return Equals(other);
5129 } 5130 }
5130 virtual bool Equals(const Instance& other) const { 5131 virtual bool Equals(const Instance& other) const;
5131 UNREACHABLE();
5132 return false;
5133 }
5134 5132
5135 virtual RawObject* HashCode() const { return raw(); } 5133 virtual RawObject* HashCode() const { return raw(); }
5136 5134
5137 // Integer is an abstract class. 5135 virtual bool IsZero() const;
5138 virtual bool IsZero() const { 5136 virtual bool IsNegative() const;
5139 UNREACHABLE(); 5137
5140 return false;
5141 }
5142 virtual bool IsNegative() const {
5143 // Number is an abstract class.
5144 UNREACHABLE();
5145 return false;
5146 }
5147 virtual double AsDoubleValue() const; 5138 virtual double AsDoubleValue() const;
5148 virtual int64_t AsInt64Value() const; 5139 virtual int64_t AsInt64Value() const;
5149 virtual uint32_t AsTruncatedUint32Value() const; 5140 virtual uint32_t AsTruncatedUint32Value() const;
5150 5141
5142 virtual bool FitsIntoSmi() const;
5143
5151 // Returns 0, -1 or 1. 5144 // Returns 0, -1 or 1.
5152 virtual int CompareWith(const Integer& other) const; 5145 virtual int CompareWith(const Integer& other) const;
5153 5146
5154 // Return the most compact presentation of an integer. 5147 // Return the most compact presentation of an integer.
5155 RawInteger* AsValidInteger() const; 5148 RawInteger* AsValidInteger() const;
5156 5149
5157 RawInteger* ArithmeticOp(Token::Kind operation, const Integer& other) const; 5150 RawInteger* ArithmeticOp(Token::Kind operation, const Integer& other) const;
5158 RawInteger* BitOp(Token::Kind operation, const Integer& other) const; 5151 RawInteger* BitOp(Token::Kind operation, const Integer& other) const;
5159 5152
5160 // Returns true if the Integer does not fit in a Javascript integer. 5153 // Returns true if the Integer does not fit in a Javascript integer.
5161 bool CheckJavascriptIntegerOverflow() const; 5154 bool CheckJavascriptIntegerOverflow() const;
5162 5155
5163 private: 5156 private:
5164 // Return an integer in the form of a RawBigint.
5165 RawBigint* AsBigint() const;
5166
5167 OBJECT_IMPLEMENTATION(Integer, Number); 5157 OBJECT_IMPLEMENTATION(Integer, Number);
5168 friend class Class; 5158 friend class Class;
5169 }; 5159 };
5170 5160
5171 5161
5172 class Smi : public Integer { 5162 class Smi : public Integer {
5173 public: 5163 public:
5174 static const intptr_t kBits = kSmiBits; 5164 static const intptr_t kBits = kSmiBits;
5175 static const intptr_t kMaxValue = kSmiMax; 5165 static const intptr_t kMaxValue = kSmiMax;
5176 static const intptr_t kMinValue = kSmiMin; 5166 static const intptr_t kMinValue = kSmiMin;
5177 5167
5178 intptr_t Value() const { 5168 intptr_t Value() const {
5179 return ValueFromRaw(raw_value()); 5169 return ValueFromRaw(raw_value());
5180 } 5170 }
5181 5171
5182 virtual bool Equals(const Instance& other) const; 5172 virtual bool Equals(const Instance& other) const;
5183 virtual bool IsZero() const { return Value() == 0; } 5173 virtual bool IsZero() const { return Value() == 0; }
5184 virtual bool IsNegative() const { return Value() < 0; } 5174 virtual bool IsNegative() const { return Value() < 0; }
5185 // Smi values are implicitly canonicalized. 5175 // Smi values are implicitly canonicalized.
5186 virtual RawInstance* CheckAndCanonicalize(const char** error_str) const { 5176 virtual RawInstance* CheckAndCanonicalize(const char** error_str) const {
5187 return reinterpret_cast<RawSmi*>(raw_value()); 5177 return reinterpret_cast<RawSmi*>(raw_value());
5188 } 5178 }
5189 5179
5190 virtual double AsDoubleValue() const; 5180 virtual double AsDoubleValue() const;
5191 virtual int64_t AsInt64Value() const; 5181 virtual int64_t AsInt64Value() const;
5192 virtual uint32_t AsTruncatedUint32Value() const; 5182 virtual uint32_t AsTruncatedUint32Value() const;
5193 5183
5184 virtual bool FitsIntoSmi() const { return true; }
5185
5194 virtual int CompareWith(const Integer& other) const; 5186 virtual int CompareWith(const Integer& other) const;
5195 5187
5196 static intptr_t InstanceSize() { return 0; } 5188 static intptr_t InstanceSize() { return 0; }
5197 5189
5198 static RawSmi* New(intptr_t value) { 5190 static RawSmi* New(intptr_t value) {
5199 intptr_t raw_smi = (value << kSmiTagShift) | kSmiTag; 5191 intptr_t raw_smi = (value << kSmiTagShift) | kSmiTag;
5200 ASSERT(ValueFromRaw(raw_smi) == value); 5192 ASSERT(ValueFromRaw(raw_smi) == value);
5201 return reinterpret_cast<RawSmi*>(raw_smi); 5193 return reinterpret_cast<RawSmi*>(raw_smi);
5202 } 5194 }
5203 5195
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
5270 virtual bool IsNegative() const { 5262 virtual bool IsNegative() const {
5271 return value() < 0; 5263 return value() < 0;
5272 } 5264 }
5273 5265
5274 virtual bool Equals(const Instance& other) const; 5266 virtual bool Equals(const Instance& other) const;
5275 5267
5276 virtual double AsDoubleValue() const; 5268 virtual double AsDoubleValue() const;
5277 virtual int64_t AsInt64Value() const; 5269 virtual int64_t AsInt64Value() const;
5278 virtual uint32_t AsTruncatedUint32Value() const; 5270 virtual uint32_t AsTruncatedUint32Value() const;
5279 5271
5272 virtual bool FitsIntoSmi() const;
5273
5280 virtual int CompareWith(const Integer& other) const; 5274 virtual int CompareWith(const Integer& other) const;
5281 5275
5282 static intptr_t InstanceSize() { 5276 static intptr_t InstanceSize() {
5283 return RoundedAllocationSize(sizeof(RawMint)); 5277 return RoundedAllocationSize(sizeof(RawMint));
5284 } 5278 }
5285 5279
5286 protected: 5280 protected:
5287 // Only Integer::NewXXX is allowed to call Mint::NewXXX directly. 5281 // Only Integer::NewXXX is allowed to call Mint::NewXXX directly.
5288 friend class Integer; 5282 friend class Integer;
5289 5283
5290 static RawMint* New(int64_t value, Heap::Space space = Heap::kNew); 5284 static RawMint* New(int64_t value, Heap::Space space = Heap::kNew);
5291 5285
5292 static RawMint* NewCanonical(int64_t value); 5286 static RawMint* NewCanonical(int64_t value);
5293 5287
5294 private: 5288 private:
5295 void set_value(int64_t value) const; 5289 void set_value(int64_t value) const;
5296 5290
5297 FINAL_HEAP_OBJECT_IMPLEMENTATION(Mint, Integer); 5291 FINAL_HEAP_OBJECT_IMPLEMENTATION(Mint, Integer);
5298 friend class Class; 5292 friend class Class;
5299 }; 5293 };
5300 5294
5301 5295
5302 class Bigint : public Integer { 5296 class Bigint : public Integer {
5303 private:
5304 typedef uint32_t Chunk;
5305 typedef uint64_t DoubleChunk;
5306 static const int kChunkSize = sizeof(Chunk);
5307
5308 public: 5297 public:
5309 virtual bool IsZero() const { return raw_ptr()->signed_length_ == 0; } 5298 virtual bool IsZero() const { return Used() == 0;}
5310 virtual bool IsNegative() const { return raw_ptr()->signed_length_ < 0; } 5299 virtual bool IsNegative() const { return Neg(); }
5311
5312 virtual bool Equals(const Instance& other) const; 5300 virtual bool Equals(const Instance& other) const;
5313 5301
5314 virtual double AsDoubleValue() const; 5302 virtual double AsDoubleValue() const;
5315 virtual int64_t AsInt64Value() const; 5303 virtual int64_t AsInt64Value() const;
5316 virtual uint32_t AsTruncatedUint32Value() const; 5304 virtual uint32_t AsTruncatedUint32Value() const;
5317 5305
5318 virtual int CompareWith(const Integer& other) const; 5306 virtual int CompareWith(const Integer& other) const;
5319 5307
5320 static const intptr_t kBytesPerElement = kChunkSize; 5308 virtual bool CheckAndCanonicalizeFields(const char** error_str) const;
5321 static const intptr_t kMaxElements = kSmiMax / kBytesPerElement;
5322 5309
5323 static intptr_t InstanceSize() { return 0; } 5310 virtual bool FitsIntoSmi() const;
5311 bool FitsIntoInt64() const;
5312 bool FitsIntoUint64() const;
5313 uint64_t AsUint64Value() const;
5324 5314
5325 static intptr_t InstanceSize(intptr_t len) { 5315 static intptr_t InstanceSize() {
5326 ASSERT(0 <= len && len <= kMaxElements); 5316 return RoundedAllocationSize(sizeof(RawBigint));
5327 return RoundedAllocationSize(sizeof(RawBigint) + (len * kBytesPerElement));
5328 } 5317 }
5329 5318
5330 protected: 5319 // Accessors used by native calls from Dart.
5331 // Only Integer::NewXXX is allowed to call Bigint::NewXXX directly. 5320 RawBool* neg() const { return raw_ptr()->neg_; }
5332 friend class Integer; 5321 void set_neg(const Bool& value) const;
5322 RawSmi* used() const { return raw_ptr()->used_; }
5323 void set_used(const Smi& value) const;
5324 RawTypedData* digits() const { return raw_ptr()->digits_; }
5325 void set_digits(const TypedData& value) const;
5333 5326
5334 RawBigint* BigArithmeticOp(Token::Kind operation, const Bigint& other) const; 5327 // Accessors used by runtime calls from C++.
5328 bool Neg() const;
5329 void SetNeg(bool value) const;
5330 intptr_t Used() const;
5331 void SetUsed(intptr_t value) const;
5332 uint32_t DigitAt(intptr_t index) const;
5333 void SetDigitAt(intptr_t index, uint32_t value) const;
5335 5334
5336 static RawBigint* New(const String& str, Heap::Space space = Heap::kNew); 5335 const char* ToDecCString(uword (*allocator)(intptr_t size)) const;
5336 const char* ToHexCString(uword (*allocator)(intptr_t size)) const;
5337
5338 static const intptr_t kExtraDigits = 4; // Same as _Bigint.EXTRA_DIGITS
5339 static const intptr_t kBitsPerDigit = 32; // Same as _Bigint.DIGIT_BITS
5340 static const int64_t kDigitBase = 1LL << kBitsPerDigit;
5341 static const int64_t kDigitMask = kDigitBase - 1;
5342
5343 static RawBigint* New(Heap::Space space = Heap::kNew);
5344
5345 static RawBigint* NewFromInt64(int64_t value,
5346 Heap::Space space = Heap::kNew);
5347
5348 static RawBigint* NewFromUint64(uint64_t value,
5349 Heap::Space space = Heap::kNew);
5350
5351 static RawBigint* NewFromShiftedInt64(int64_t value, intptr_t shift,
5352 Heap::Space space = Heap::kNew);
5353
5354 static RawBigint* NewFromCString(const char* str,
5355 Heap::Space space = Heap::kNew);
5337 5356
5338 // Returns a canonical Bigint object allocated in the old gen space. 5357 // Returns a canonical Bigint object allocated in the old gen space.
5339 static RawBigint* NewCanonical(const String& str); 5358 static RawBigint* NewCanonical(const String& str);
5340 5359
5341 private: 5360 private:
5342 Chunk GetChunkAt(intptr_t i) const { 5361 static RawBigint* NewFromHexCString(const char* str,
5343 return *ChunkAddr(i); 5362 Heap::Space space = Heap::kNew);
5344 } 5363 static RawBigint* NewFromDecCString(const char* str,
5364 Heap::Space space = Heap::kNew);
5345 5365
5346 void SetChunkAt(intptr_t i, Chunk newValue) const { 5366 // Make sure at least 'length' _digits are allocated.
5347 *ChunkAddr(i) = newValue; 5367 // Copy existing _digits if reallocation is necessary.
5348 } 5368 // TODO(regis): Check that we are not preserving digits unnecessarily.
5369 void EnsureLength(intptr_t length, Heap::Space space = Heap::kNew) const;
5349 5370
5350 // Returns the number of chunks in use. 5371 // Do not count zero high digits as used.
5351 intptr_t Length() const { 5372 void Clamp() const;
5352 intptr_t signed_length = raw_ptr()->signed_length_;
5353 return Utils::Abs(signed_length);
5354 }
5355 5373
5356 // SetLength does not change the sign. 5374 bool IsClamped() const;
5357 void SetLength(intptr_t length) const {
5358 ASSERT(length >= 0);
5359 bool is_negative = IsNegative();
5360 raw_ptr()->signed_length_ = length;
5361 if (is_negative) ToggleSign();
5362 }
5363
5364 void SetSign(bool is_negative) const {
5365 if (is_negative != IsNegative()) {
5366 ToggleSign();
5367 }
5368 }
5369
5370 void ToggleSign() const {
5371 raw_ptr()->signed_length_ = -raw_ptr()->signed_length_;
5372 }
5373
5374 Chunk* ChunkAddr(intptr_t index) const {
5375 ASSERT(0 <= index);
5376 ASSERT(index < Length());
5377 uword digits_start = reinterpret_cast<uword>(raw_ptr()) + sizeof(RawBigint);
5378 return &(reinterpret_cast<Chunk*>(digits_start)[index]);
5379 }
5380 5375
5381 static RawBigint* Allocate(intptr_t length, Heap::Space space = Heap::kNew); 5376 static RawBigint* Allocate(intptr_t length, Heap::Space space = Heap::kNew);
5382 5377
5383 FINAL_HEAP_OBJECT_IMPLEMENTATION(Bigint, Integer); 5378 FINAL_HEAP_OBJECT_IMPLEMENTATION(Bigint, Integer);
5384 friend class BigintOperations;
5385 friend class Class; 5379 friend class Class;
5386 }; 5380 };
5387 5381
5388 5382
5389 // Class Double represents class Double in corelib_impl, which implements 5383 // Class Double represents class Double in corelib_impl, which implements
5390 // abstract class double in corelib. 5384 // abstract class double in corelib.
5391 class Double : public Number { 5385 class Double : public Number {
5392 public: 5386 public:
5393 double value() const { 5387 double value() const {
5394 return raw_ptr()->value_; 5388 return raw_ptr()->value_;
(...skipping 1193 matching lines...) Expand 10 before | Expand all | Expand 10 after
6588 intptr_t cid = raw()->GetClassId(); 6582 intptr_t cid = raw()->GetClassId();
6589 return (ElementSizeInBytes(cid) * Length()); 6583 return (ElementSizeInBytes(cid) * Length());
6590 } 6584 }
6591 6585
6592 void* DataAddr(intptr_t byte_offset) const { 6586 void* DataAddr(intptr_t byte_offset) const {
6593 ASSERT((byte_offset == 0) || 6587 ASSERT((byte_offset == 0) ||
6594 ((byte_offset > 0) && (byte_offset < LengthInBytes()))); 6588 ((byte_offset > 0) && (byte_offset < LengthInBytes())));
6595 return reinterpret_cast<void*>(raw_ptr()->data() + byte_offset); 6589 return reinterpret_cast<void*>(raw_ptr()->data() + byte_offset);
6596 } 6590 }
6597 6591
6592 virtual bool CanonicalizeEquals(const Instance& other) const;
6593
6598 #define TYPED_GETTER_SETTER(name, type) \ 6594 #define TYPED_GETTER_SETTER(name, type) \
6599 type Get##name(intptr_t byte_offset) const { \ 6595 type Get##name(intptr_t byte_offset) const { \
6600 return *reinterpret_cast<type*>(DataAddr(byte_offset)); \ 6596 return *reinterpret_cast<type*>(DataAddr(byte_offset)); \
6601 } \ 6597 } \
6602 void Set##name(intptr_t byte_offset, type value) const { \ 6598 void Set##name(intptr_t byte_offset, type value) const { \
6603 *reinterpret_cast<type*>(DataAddr(byte_offset)) = value; \ 6599 *reinterpret_cast<type*>(DataAddr(byte_offset)) = value; \
6604 } 6600 }
6605 TYPED_GETTER_SETTER(Int8, int8_t) 6601 TYPED_GETTER_SETTER(Int8, int8_t)
6606 TYPED_GETTER_SETTER(Uint8, uint8_t) 6602 TYPED_GETTER_SETTER(Uint8, uint8_t)
6607 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
7420 7416
7421 7417
7422 RawObject* MegamorphicCache::GetTargetFunction(const Array& array, 7418 RawObject* MegamorphicCache::GetTargetFunction(const Array& array,
7423 intptr_t index) { 7419 intptr_t index) {
7424 return array.At((index * kEntryLength) + kTargetFunctionIndex); 7420 return array.At((index * kEntryLength) + kTargetFunctionIndex);
7425 } 7421 }
7426 7422
7427 } // namespace dart 7423 } // namespace dart
7428 7424
7429 #endif // VM_OBJECT_H_ 7425 #endif // VM_OBJECT_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698