| Index: src/hydrogen.h
|
| diff --git a/src/hydrogen.h b/src/hydrogen.h
|
| index 508912eff9988a8a2ac1a1e65cd6fb58372eda4d..e01a2800b4a6b7fb8ae17cb5c101559bf3880590 100644
|
| --- a/src/hydrogen.h
|
| +++ b/src/hydrogen.h
|
| @@ -1294,7 +1294,7 @@ class HGraphBuilder {
|
| HValue* length,
|
| HValue* key,
|
| bool is_js_array,
|
| - bool is_store);
|
| + PropertyAccessType access_type);
|
|
|
| HValue* BuildCopyElementsOnWrite(HValue* object,
|
| HValue* elements,
|
| @@ -1351,7 +1351,7 @@ class HGraphBuilder {
|
| HValue* val,
|
| bool is_js_array,
|
| ElementsKind elements_kind,
|
| - bool is_store,
|
| + PropertyAccessType access_type,
|
| LoadKeyedHoleMode load_mode,
|
| KeyedAccessStoreMode store_mode);
|
|
|
| @@ -1361,7 +1361,7 @@ class HGraphBuilder {
|
| HValue* val,
|
| HValue* dependency,
|
| ElementsKind elements_kind,
|
| - bool is_store,
|
| + PropertyAccessType access_type,
|
| LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE);
|
|
|
| HLoadNamedField* BuildLoadNamedField(HValue* object, HObjectAccess access);
|
| @@ -1370,7 +1370,7 @@ class HGraphBuilder {
|
| HInstruction* AddLoadStringLength(HValue* string);
|
| HStoreNamedField* AddStoreMapNoWriteBarrier(HValue* object, HValue* map) {
|
| HStoreNamedField* store_map = Add<HStoreNamedField>(
|
| - object, HObjectAccess::ForMap(), map, INITIALIZING_STORE);
|
| + object, HObjectAccess::ForMap(), map);
|
| store_map->SkipWriteBarrier();
|
| return store_map;
|
| }
|
| @@ -2184,6 +2184,8 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
|
| AST_NODE_LIST(DECLARE_VISIT)
|
| #undef DECLARE_VISIT
|
|
|
| + Type* ToType(Handle<Map> map) { return IC::MapToType<Type>(map, zone()); }
|
| +
|
| private:
|
| // Helpers for flow graph construction.
|
| enum GlobalPropertyAccess {
|
| @@ -2192,7 +2194,7 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
|
| };
|
| GlobalPropertyAccess LookupGlobalProperty(Variable* var,
|
| LookupResult* lookup,
|
| - bool is_store);
|
| + PropertyAccessType access_type);
|
|
|
| void EnsureArgumentsArePushedForAccess();
|
| bool TryArgumentsAccess(Property* expr);
|
| @@ -2214,9 +2216,11 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
|
| bool TryInlineCall(Call* expr);
|
| bool TryInlineConstruct(CallNew* expr, HValue* implicit_return_value);
|
| bool TryInlineGetter(Handle<JSFunction> getter,
|
| + Handle<Map> receiver_map,
|
| BailoutId ast_id,
|
| BailoutId return_id);
|
| bool TryInlineSetter(Handle<JSFunction> setter,
|
| + Handle<Map> receiver_map,
|
| BailoutId id,
|
| BailoutId assignment_id,
|
| HValue* implicit_return_value);
|
| @@ -2227,14 +2231,28 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
|
| HValue* receiver,
|
| Handle<Map> receiver_map);
|
| bool TryInlineBuiltinFunctionCall(Call* expr);
|
| + enum ApiCallType {
|
| + kCallApiFunction,
|
| + kCallApiMethod,
|
| + kCallApiGetter,
|
| + kCallApiSetter
|
| + };
|
| bool TryInlineApiMethodCall(Call* expr,
|
| HValue* receiver,
|
| - Handle<Map> receiver_map);
|
| + SmallMapList* receiver_types);
|
| bool TryInlineApiFunctionCall(Call* expr, HValue* receiver);
|
| - bool TryInlineApiCall(Call* expr,
|
| - HValue* receiver,
|
| - Handle<Map> receiver_map,
|
| - bool is_function_call);
|
| + bool TryInlineApiGetter(Handle<JSFunction> function,
|
| + Handle<Map> receiver_map,
|
| + BailoutId ast_id);
|
| + bool TryInlineApiSetter(Handle<JSFunction> function,
|
| + Handle<Map> receiver_map,
|
| + BailoutId ast_id);
|
| + bool TryInlineApiCall(Handle<JSFunction> function,
|
| + HValue* receiver,
|
| + SmallMapList* receiver_maps,
|
| + int argc,
|
| + BailoutId ast_id,
|
| + ApiCallType call_type);
|
|
|
| // If --trace-inlining, print a line of the inlining trace. Inlining
|
| // succeeded if the reason string is NULL and failed if there is a
|
| @@ -2249,11 +2267,13 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
|
|
|
| void HandlePropertyAssignment(Assignment* expr);
|
| void HandleCompoundAssignment(Assignment* expr);
|
| - void HandlePolymorphicLoadNamedField(BailoutId ast_id,
|
| - BailoutId return_id,
|
| - HValue* object,
|
| - SmallMapList* types,
|
| - Handle<String> name);
|
| + void HandlePolymorphicNamedFieldAccess(PropertyAccessType access_type,
|
| + BailoutId ast_id,
|
| + BailoutId return_id,
|
| + HValue* object,
|
| + HValue* value,
|
| + SmallMapList* types,
|
| + Handle<String> name);
|
|
|
| void VisitTypedArrayInitialize(CallRuntime* expr);
|
|
|
| @@ -2265,10 +2285,12 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
|
| class PropertyAccessInfo {
|
| public:
|
| PropertyAccessInfo(HOptimizedGraphBuilder* builder,
|
| - Handle<HeapType> type,
|
| + PropertyAccessType access_type,
|
| + Type* type,
|
| Handle<String> name)
|
| : lookup_(builder->isolate()),
|
| builder_(builder),
|
| + access_type_(access_type),
|
| type_(type),
|
| name_(name),
|
| access_(HObjectAccess::ForMap()) { }
|
| @@ -2276,7 +2298,7 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
|
| // Checkes whether this PropertyAccessInfo can be handled as a monomorphic
|
| // load named. It additionally fills in the fields necessary to generate the
|
| // lookup code.
|
| - bool CanLoadMonomorphic();
|
| + bool CanAccessMonomorphic();
|
|
|
| // Checks whether all types behave uniform when loading name. If all maps
|
| // behave the same, a single monomorphic load instruction can be emitted,
|
| @@ -2284,14 +2306,18 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
|
| // an instance of any of the types.
|
| // This method skips the first type in types, assuming that this
|
| // PropertyAccessInfo is built for types->first().
|
| - bool CanLoadAsMonomorphic(SmallMapList* types);
|
| + bool CanAccessAsMonomorphic(SmallMapList* types);
|
|
|
| Handle<Map> map() {
|
| - if (type_->Is(HeapType::Number())) {
|
| + if (type_->Is(Type::Number())) {
|
| Context* context = current_info()->closure()->context();
|
| context = context->native_context();
|
| return handle(context->number_function()->initial_map());
|
| - } else if (type_->Is(HeapType::String())) {
|
| + } else if (type_->Is(Type::Boolean())) {
|
| + Context* context = current_info()->closure()->context();
|
| + context = context->native_context();
|
| + return handle(context->boolean_function()->initial_map());
|
| + } else if (type_->Is(Type::String())) {
|
| Context* context = current_info()->closure()->context();
|
| context = context->native_context();
|
| return handle(context->string_function()->initial_map());
|
| @@ -2299,26 +2325,25 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
|
| return type_->AsClass();
|
| }
|
| }
|
| - Handle<HeapType> type() const { return type_; }
|
| + Type* type() const { return type_; }
|
| Handle<String> name() const { return name_; }
|
|
|
| bool IsJSObjectFieldAccessor() {
|
| int offset; // unused
|
| - return Accessors::IsJSObjectFieldAccessor(type_, name_, &offset);
|
| + return Accessors::IsJSObjectFieldAccessor<Type>(type_, name_, &offset);
|
| }
|
|
|
| bool GetJSObjectFieldAccess(HObjectAccess* access) {
|
| - if (IsArrayLength()) {
|
| - *access = HObjectAccess::ForArrayLength(map()->elements_kind());
|
| - return true;
|
| - }
|
| int offset;
|
| - if (Accessors::IsJSObjectFieldAccessor(type_, name_, &offset)) {
|
| - if (type_->Is(HeapType::String())) {
|
| + if (Accessors::IsJSObjectFieldAccessor<Type>(type_, name_, &offset)) {
|
| + if (type_->Is(Type::String())) {
|
| ASSERT(name_->Equals(isolate()->heap()->length_string()));
|
| *access = HObjectAccess::ForStringLength();
|
| + } else if (type_->Is(Type::Array())) {
|
| + ASSERT(name_->Equals(isolate()->heap()->length_string()));
|
| + *access = HObjectAccess::ForArrayLength(map()->elements_kind());
|
| } else {
|
| - *access = HObjectAccess::ForJSObjectOffset(offset);
|
| + *access = HObjectAccess::ForMapAndOffset(map(), offset);
|
| }
|
| return true;
|
| }
|
| @@ -2326,26 +2351,24 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
|
| }
|
|
|
| bool has_holder() { return !holder_.is_null(); }
|
| + bool IsLoad() const { return access_type_ == LOAD; }
|
|
|
| LookupResult* lookup() { return &lookup_; }
|
| Handle<JSObject> holder() { return holder_; }
|
| Handle<JSFunction> accessor() { return accessor_; }
|
| Handle<Object> constant() { return constant_; }
|
| + Handle<Object> transition() { return transition_; }
|
| HObjectAccess access() { return access_; }
|
|
|
| private:
|
| + Type* ToType(Handle<Map> map) { return builder_->ToType(map); }
|
| Isolate* isolate() { return lookup_.isolate(); }
|
| CompilationInfo* current_info() { return builder_->current_info(); }
|
|
|
| - bool IsArrayLength() {
|
| - return map()->instance_type() == JS_ARRAY_TYPE &&
|
| - name_->Equals(isolate()->heap()->length_string());
|
| - }
|
| -
|
| bool LoadResult(Handle<Map> map);
|
| bool LookupDescriptor();
|
| bool LookupInPrototypes();
|
| - bool IsCompatibleForLoad(PropertyAccessInfo* other);
|
| + bool IsCompatible(PropertyAccessInfo* other);
|
|
|
| void GeneralizeRepresentation(Representation r) {
|
| access_ = access_.WithRepresentation(
|
| @@ -2354,31 +2377,34 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
|
|
|
| LookupResult lookup_;
|
| HOptimizedGraphBuilder* builder_;
|
| - Handle<HeapType> type_;
|
| + PropertyAccessType access_type_;
|
| + Type* type_;
|
| Handle<String> name_;
|
| Handle<JSObject> holder_;
|
| Handle<JSFunction> accessor_;
|
| + Handle<JSObject> api_holder_;
|
| Handle<Object> constant_;
|
| + Handle<Map> transition_;
|
| HObjectAccess access_;
|
| };
|
|
|
| - HInstruction* BuildLoadMonomorphic(PropertyAccessInfo* info,
|
| - HValue* object,
|
| - HValue* checked_object,
|
| - BailoutId ast_id,
|
| - BailoutId return_id,
|
| - bool can_inline_accessor = true);
|
| -
|
| - void HandlePolymorphicStoreNamedField(BailoutId assignment_id,
|
| - HValue* object,
|
| - HValue* value,
|
| - SmallMapList* types,
|
| - Handle<String> name);
|
| - bool TryStorePolymorphicAsMonomorphic(BailoutId assignment_id,
|
| - HValue* object,
|
| - HValue* value,
|
| - SmallMapList* types,
|
| - Handle<String> name);
|
| + HInstruction* BuildMonomorphicAccess(PropertyAccessInfo* info,
|
| + HValue* object,
|
| + HValue* checked_object,
|
| + HValue* value,
|
| + BailoutId ast_id,
|
| + BailoutId return_id,
|
| + bool can_inline_accessor = true);
|
| +
|
| + HInstruction* BuildNamedAccess(PropertyAccessType access,
|
| + BailoutId ast_id,
|
| + BailoutId reutrn_id,
|
| + Expression* expr,
|
| + HValue* object,
|
| + Handle<String> name,
|
| + HValue* value,
|
| + bool is_uninitialized = false);
|
| +
|
| void HandlePolymorphicCallNamed(Call* expr,
|
| HValue* receiver,
|
| SmallMapList* types,
|
| @@ -2401,13 +2427,22 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
|
|
|
| HInstruction* BuildStringCharCodeAt(HValue* string,
|
| HValue* index);
|
| - HValue* BuildBinaryOperation(BinaryOperation* expr,
|
| - HValue* left,
|
| - HValue* right);
|
| +
|
| + enum PushBeforeSimulateBehavior {
|
| + PUSH_BEFORE_SIMULATE,
|
| + NO_PUSH_BEFORE_SIMULATE
|
| + };
|
| + HValue* BuildBinaryOperation(
|
| + BinaryOperation* expr,
|
| + HValue* left,
|
| + HValue* right,
|
| + PushBeforeSimulateBehavior push_sim_result);
|
| HInstruction* BuildIncrement(bool returns_original_input,
|
| CountOperation* expr);
|
| - HInstruction* BuildLoadKeyedGeneric(HValue* object,
|
| - HValue* key);
|
| + HInstruction* BuildKeyedGeneric(PropertyAccessType access_type,
|
| + HValue* object,
|
| + HValue* key,
|
| + HValue* value);
|
|
|
| HInstruction* TryBuildConsolidatedElementLoad(HValue* object,
|
| HValue* key,
|
| @@ -2421,14 +2456,14 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
|
| HValue* val,
|
| HValue* dependency,
|
| Handle<Map> map,
|
| - bool is_store,
|
| + PropertyAccessType access_type,
|
| KeyedAccessStoreMode store_mode);
|
|
|
| HValue* HandlePolymorphicElementAccess(HValue* object,
|
| HValue* key,
|
| HValue* val,
|
| SmallMapList* maps,
|
| - bool is_store,
|
| + PropertyAccessType access_type,
|
| KeyedAccessStoreMode store_mode,
|
| bool* has_side_effects);
|
|
|
| @@ -2436,12 +2471,14 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
|
| HValue* key,
|
| HValue* val,
|
| Expression* expr,
|
| - bool is_store,
|
| + PropertyAccessType access_type,
|
| bool* has_side_effects);
|
|
|
| - HInstruction* BuildLoadNamedGeneric(HValue* object,
|
| - Handle<String> name,
|
| - Property* expr);
|
| + HInstruction* BuildNamedGeneric(PropertyAccessType access,
|
| + HValue* object,
|
| + Handle<String> name,
|
| + HValue* value,
|
| + bool is_uninitialized = false);
|
|
|
| HCheckMaps* AddCheckMap(HValue* object, Handle<Map> map);
|
|
|
| @@ -2465,21 +2502,9 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
|
| BailoutId return_id,
|
| bool is_uninitialized = false);
|
|
|
| - HInstruction* BuildStoreNamedField(HValue* object,
|
| - Handle<String> name,
|
| - HValue* value,
|
| - Handle<Map> map,
|
| - LookupResult* lookup);
|
| - HInstruction* BuildStoreNamedGeneric(HValue* object,
|
| - Handle<String> name,
|
| - HValue* value);
|
| - HInstruction* BuildStoreNamedMonomorphic(HValue* object,
|
| - Handle<String> name,
|
| - HValue* value,
|
| - Handle<Map> map);
|
| - HInstruction* BuildStoreKeyedGeneric(HValue* object,
|
| - HValue* key,
|
| - HValue* value);
|
| + HInstruction* BuildStoreNamedField(PropertyAccessInfo* info,
|
| + HValue* checked_object,
|
| + HValue* value);
|
|
|
| HValue* BuildContextChainWalk(Variable* var);
|
|
|
|
|